test_submission.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. # Copyright 2021-2024 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. from datetime import datetime
  12. import pytest
  13. from taipy.core import TaskId
  14. from taipy.core.job._job_manager_factory import _JobManagerFactory
  15. from taipy.core.job.job import Job
  16. from taipy.core.job.status import Status
  17. from taipy.core.submission._submission_manager_factory import _SubmissionManagerFactory
  18. from taipy.core.submission.submission import Submission
  19. from taipy.core.submission.submission_status import SubmissionStatus
  20. from taipy.core.task._task_manager_factory import _TaskManagerFactory
  21. from taipy.core.task.task import Task
  22. def test_create_submission(scenario, job, current_datetime):
  23. submission_1 = Submission(scenario.id, scenario._ID_PREFIX, scenario.config_id)
  24. assert submission_1.id is not None
  25. assert submission_1.entity_id == scenario.id
  26. assert submission_1.entity_type == scenario._ID_PREFIX
  27. assert submission_1.entity_config_id == scenario.config_id
  28. assert submission_1.jobs == []
  29. assert isinstance(submission_1.creation_date, datetime)
  30. assert submission_1._submission_status == SubmissionStatus.SUBMITTED
  31. assert submission_1._version is not None
  32. submission_2 = Submission(
  33. scenario.id,
  34. scenario._ID_PREFIX,
  35. scenario.config_id,
  36. "submission_id",
  37. [job],
  38. current_datetime,
  39. SubmissionStatus.COMPLETED,
  40. "version_id",
  41. )
  42. assert submission_2.id == "submission_id"
  43. assert submission_2.entity_id == scenario.id
  44. assert submission_2.entity_type == scenario._ID_PREFIX
  45. assert submission_2.entity_config_id == scenario.config_id
  46. assert submission_2._jobs == [job]
  47. assert submission_2.creation_date == current_datetime
  48. assert submission_2._submission_status == SubmissionStatus.COMPLETED
  49. assert submission_2._version == "version_id"
  50. class MockJob:
  51. def __init__(self, id: str, status):
  52. self.status = status
  53. self.id = id
  54. def is_failed(self):
  55. return self.status == Status.FAILED
  56. def is_canceled(self):
  57. return self.status == Status.CANCELED
  58. def is_blocked(self):
  59. return self.status == Status.BLOCKED
  60. def is_pending(self):
  61. return self.status == Status.PENDING
  62. def is_running(self):
  63. return self.status == Status.RUNNING
  64. def is_completed(self):
  65. return self.status == Status.COMPLETED
  66. def is_skipped(self):
  67. return self.status == Status.SKIPPED
  68. def is_abandoned(self):
  69. return self.status == Status.ABANDONED
  70. def is_submitted(self):
  71. return self.status == Status.SUBMITTED
  72. def __test_update_submission_status(job_ids, expected_submission_status):
  73. jobs = {
  74. "job0_submitted": MockJob("job0_submitted", Status.SUBMITTED),
  75. "job1_failed": MockJob("job1_failed", Status.FAILED),
  76. "job2_canceled": MockJob("job2_canceled", Status.CANCELED),
  77. "job3_blocked": MockJob("job3_blocked", Status.BLOCKED),
  78. "job4_pending": MockJob("job4_pending", Status.PENDING),
  79. "job5_running": MockJob("job5_running", Status.RUNNING),
  80. "job6_completed": MockJob("job6_completed", Status.COMPLETED),
  81. "job7_skipped": MockJob("job7_skipped", Status.SKIPPED),
  82. "job8_abandoned": MockJob("job8_abandoned", Status.ABANDONED),
  83. }
  84. submission = Submission("submission_id", "ENTITY_TYPE", "entity_config_id")
  85. submission.jobs = [jobs[job_id] for job_id in job_ids]
  86. for job_id in job_ids:
  87. job = jobs[job_id]
  88. submission._update_submission_status(job)
  89. assert submission.submission_status == expected_submission_status
  90. @pytest.mark.parametrize(
  91. "job_ids, expected_submission_status",
  92. [
  93. (["job1_failed"], SubmissionStatus.FAILED),
  94. (["job2_canceled"], SubmissionStatus.CANCELED),
  95. (["job3_blocked"], SubmissionStatus.BLOCKED),
  96. (["job4_pending"], SubmissionStatus.PENDING),
  97. (["job5_running"], SubmissionStatus.RUNNING),
  98. (["job6_completed"], SubmissionStatus.COMPLETED),
  99. (["job7_skipped"], SubmissionStatus.COMPLETED),
  100. (["job8_abandoned"], SubmissionStatus.UNDEFINED),
  101. ],
  102. )
  103. def test_update_single_submission_status(job_ids, expected_submission_status):
  104. __test_update_submission_status(job_ids, expected_submission_status)
  105. @pytest.mark.parametrize(
  106. "job_ids, expected_submission_status",
  107. [
  108. (["job1_failed", "job1_failed"], SubmissionStatus.FAILED),
  109. (["job1_failed", "job2_canceled"], SubmissionStatus.FAILED),
  110. (["job1_failed", "job3_blocked"], SubmissionStatus.FAILED),
  111. (["job1_failed", "job4_pending"], SubmissionStatus.FAILED),
  112. (["job1_failed", "job5_running"], SubmissionStatus.FAILED),
  113. (["job1_failed", "job6_completed"], SubmissionStatus.FAILED),
  114. (["job1_failed", "job7_skipped"], SubmissionStatus.FAILED),
  115. (["job1_failed", "job8_abandoned"], SubmissionStatus.FAILED),
  116. (["job2_canceled", "job1_failed"], SubmissionStatus.FAILED),
  117. (["job3_blocked", "job1_failed"], SubmissionStatus.FAILED),
  118. (["job4_pending", "job1_failed"], SubmissionStatus.FAILED),
  119. (["job5_running", "job1_failed"], SubmissionStatus.FAILED),
  120. (["job6_completed", "job1_failed"], SubmissionStatus.FAILED),
  121. (["job7_skipped", "job1_failed"], SubmissionStatus.FAILED),
  122. (["job8_abandoned", "job1_failed"], SubmissionStatus.FAILED),
  123. ],
  124. )
  125. def test_update_submission_status_with_one_failed_job_in_jobs(job_ids, expected_submission_status):
  126. __test_update_submission_status(job_ids, expected_submission_status)
  127. @pytest.mark.parametrize(
  128. "job_ids, expected_submission_status",
  129. [
  130. (["job2_canceled", "job2_canceled"], SubmissionStatus.CANCELED),
  131. (["job2_canceled", "job3_blocked"], SubmissionStatus.CANCELED),
  132. (["job2_canceled", "job4_pending"], SubmissionStatus.CANCELED),
  133. (["job2_canceled", "job5_running"], SubmissionStatus.CANCELED),
  134. (["job2_canceled", "job6_completed"], SubmissionStatus.CANCELED),
  135. (["job2_canceled", "job7_skipped"], SubmissionStatus.CANCELED),
  136. (["job2_canceled", "job8_abandoned"], SubmissionStatus.CANCELED),
  137. (["job3_blocked", "job2_canceled"], SubmissionStatus.CANCELED),
  138. (["job4_pending", "job2_canceled"], SubmissionStatus.CANCELED),
  139. (["job5_running", "job2_canceled"], SubmissionStatus.CANCELED),
  140. (["job6_completed", "job2_canceled"], SubmissionStatus.CANCELED),
  141. (["job7_skipped", "job2_canceled"], SubmissionStatus.CANCELED),
  142. (["job8_abandoned", "job2_canceled"], SubmissionStatus.CANCELED),
  143. ],
  144. )
  145. def test_update_submission_status_with_one_canceled_job_in_jobs(job_ids, expected_submission_status):
  146. __test_update_submission_status(job_ids, expected_submission_status)
  147. @pytest.mark.parametrize(
  148. "job_ids, expected_submission_status",
  149. [
  150. (["job4_pending", "job3_blocked"], SubmissionStatus.PENDING),
  151. (["job4_pending", "job4_pending"], SubmissionStatus.PENDING),
  152. (["job4_pending", "job6_completed"], SubmissionStatus.PENDING),
  153. (["job4_pending", "job7_skipped"], SubmissionStatus.PENDING),
  154. (["job3_blocked", "job4_pending"], SubmissionStatus.PENDING),
  155. (["job6_completed", "job4_pending"], SubmissionStatus.PENDING),
  156. (["job7_skipped", "job4_pending"], SubmissionStatus.PENDING),
  157. ],
  158. )
  159. def test_update_submission_status_with_no_failed_or_cancel_one_pending_in_jobs(job_ids, expected_submission_status):
  160. __test_update_submission_status(job_ids, expected_submission_status)
  161. @pytest.mark.parametrize(
  162. "job_ids, expected_submission_status",
  163. [
  164. (["job5_running", "job3_blocked"], SubmissionStatus.RUNNING),
  165. (["job5_running", "job4_pending"], SubmissionStatus.RUNNING),
  166. (["job5_running", "job5_running"], SubmissionStatus.RUNNING),
  167. (["job5_running", "job6_completed"], SubmissionStatus.RUNNING),
  168. (["job5_running", "job7_skipped"], SubmissionStatus.RUNNING),
  169. (["job3_blocked", "job5_running"], SubmissionStatus.RUNNING),
  170. (["job4_pending", "job5_running"], SubmissionStatus.RUNNING),
  171. (["job6_completed", "job5_running"], SubmissionStatus.RUNNING),
  172. (["job7_skipped", "job5_running"], SubmissionStatus.RUNNING),
  173. ],
  174. )
  175. def test_update_submission_status_with_no_failed_cancel_nor_pending_one_running_in_jobs(
  176. job_ids, expected_submission_status
  177. ):
  178. __test_update_submission_status(job_ids, expected_submission_status)
  179. @pytest.mark.parametrize(
  180. "job_ids, expected_submission_status",
  181. [
  182. (["job3_blocked", "job3_blocked"], SubmissionStatus.BLOCKED),
  183. (["job3_blocked", "job6_completed"], SubmissionStatus.BLOCKED),
  184. (["job3_blocked", "job7_skipped"], SubmissionStatus.BLOCKED),
  185. (["job6_completed", "job3_blocked"], SubmissionStatus.BLOCKED),
  186. (["job7_skipped", "job3_blocked"], SubmissionStatus.BLOCKED),
  187. ],
  188. )
  189. def test_update_submission_status_with_no_failed_cancel_pending_nor_running_one_blocked_in_jobs(
  190. job_ids, expected_submission_status
  191. ):
  192. __test_update_submission_status(job_ids, expected_submission_status)
  193. @pytest.mark.parametrize(
  194. "job_ids, expected_submission_status",
  195. [
  196. (["job6_completed", "job6_completed"], SubmissionStatus.COMPLETED),
  197. (["job6_completed", "job7_skipped"], SubmissionStatus.COMPLETED),
  198. (["job7_skipped", "job6_completed"], SubmissionStatus.COMPLETED),
  199. (["job7_skipped", "job7_skipped"], SubmissionStatus.COMPLETED),
  200. ],
  201. )
  202. def test_update_submission_status_with_only_completed_or_skipped_in_jobs(job_ids, expected_submission_status):
  203. __test_update_submission_status(job_ids, expected_submission_status)
  204. @pytest.mark.parametrize(
  205. "job_ids, expected_submission_status",
  206. [
  207. (["job3_blocked", "job8_abandoned"], SubmissionStatus.UNDEFINED),
  208. (["job4_pending", "job8_abandoned"], SubmissionStatus.UNDEFINED),
  209. (["job5_running", "job8_abandoned"], SubmissionStatus.UNDEFINED),
  210. (["job6_completed", "job8_abandoned"], SubmissionStatus.UNDEFINED),
  211. (["job7_skipped", "job8_abandoned"], SubmissionStatus.UNDEFINED),
  212. (["job8_abandoned", "job8_abandoned"], SubmissionStatus.UNDEFINED),
  213. (["job8_abandoned", "job3_blocked"], SubmissionStatus.UNDEFINED),
  214. (["job8_abandoned", "job4_pending"], SubmissionStatus.UNDEFINED),
  215. (["job8_abandoned", "job5_running"], SubmissionStatus.UNDEFINED),
  216. (["job8_abandoned", "job6_completed"], SubmissionStatus.UNDEFINED),
  217. (["job8_abandoned", "job7_skipped"], SubmissionStatus.UNDEFINED),
  218. ],
  219. )
  220. def test_update_submission_status_with_wrong_case_abandoned_without_cancel_or_failed_in_jobs(
  221. job_ids, expected_submission_status
  222. ):
  223. __test_update_submission_status(job_ids, expected_submission_status)
  224. def test_auto_set_and_reload():
  225. task = Task(config_id="name_1", properties={}, function=print, id=TaskId("task_1"))
  226. submission_1 = Submission(task.id, task._ID_PREFIX, task.config_id)
  227. job_1 = Job("job_1", task, submission_1.id, submission_1.entity_id)
  228. job_2 = Job("job_2", task, submission_1.id, submission_1.entity_id)
  229. _TaskManagerFactory._build_manager()._set(task)
  230. _SubmissionManagerFactory._build_manager()._set(submission_1)
  231. _JobManagerFactory._build_manager()._set(job_1)
  232. _JobManagerFactory._build_manager()._set(job_2)
  233. submission_2 = _SubmissionManagerFactory._build_manager()._get(submission_1)
  234. assert submission_1.id == submission_2.id
  235. assert submission_1.entity_id == submission_2.entity_id
  236. assert submission_1.creation_date == submission_2.creation_date
  237. assert submission_1.submission_status == submission_2.submission_status
  238. # auto set & reload on jobs attribute
  239. assert submission_1.jobs == []
  240. assert submission_2.jobs == []
  241. submission_1.jobs = [job_1]
  242. assert submission_1.jobs == [job_1]
  243. assert submission_2.jobs == [job_1]
  244. submission_2.jobs = [job_2]
  245. assert submission_1.jobs == [job_2]
  246. assert submission_2.jobs == [job_2]
  247. submission_1.jobs = [job_1, job_2]
  248. assert submission_1.jobs == [job_1, job_2]
  249. assert submission_2.jobs == [job_1, job_2]
  250. submission_2.jobs = [job_2, job_1]
  251. assert submission_1.jobs == [job_2, job_1]
  252. assert submission_2.jobs == [job_2, job_1]
  253. # auto set & reload on submission_status attribute
  254. assert submission_1.submission_status == SubmissionStatus.SUBMITTED
  255. assert submission_2.submission_status == SubmissionStatus.SUBMITTED
  256. submission_1.submission_status = SubmissionStatus.BLOCKED
  257. assert submission_1.submission_status == SubmissionStatus.BLOCKED
  258. assert submission_2.submission_status == SubmissionStatus.BLOCKED
  259. submission_2.submission_status = SubmissionStatus.COMPLETED
  260. assert submission_1.submission_status == SubmissionStatus.COMPLETED
  261. assert submission_2.submission_status == SubmissionStatus.COMPLETED
  262. with submission_1 as submission:
  263. assert submission.jobs == [job_2, job_1]
  264. assert submission.submission_status == SubmissionStatus.COMPLETED
  265. submission.jobs = [job_1]
  266. submission.submission_status = SubmissionStatus.PENDING
  267. assert submission.jobs == [job_2, job_1]
  268. assert submission.submission_status == SubmissionStatus.COMPLETED
  269. assert submission_1.jobs == [job_1]
  270. assert submission_1.submission_status == SubmissionStatus.PENDING
  271. assert submission_2.jobs == [job_1]
  272. assert submission_2.submission_status == SubmissionStatus.PENDING
  273. @pytest.mark.parametrize(
  274. "job_statuses, expected_submission_statuses",
  275. [
  276. (
  277. [Status.SUBMITTED, Status.PENDING, Status.RUNNING, Status.COMPLETED],
  278. [SubmissionStatus.PENDING, SubmissionStatus.PENDING, SubmissionStatus.RUNNING, SubmissionStatus.COMPLETED],
  279. ),
  280. (
  281. [Status.SUBMITTED, Status.PENDING, Status.RUNNING, Status.SKIPPED],
  282. [SubmissionStatus.PENDING, SubmissionStatus.PENDING, SubmissionStatus.RUNNING, SubmissionStatus.COMPLETED],
  283. ),
  284. (
  285. [Status.SUBMITTED, Status.PENDING, Status.RUNNING, Status.FAILED],
  286. [SubmissionStatus.PENDING, SubmissionStatus.PENDING, SubmissionStatus.RUNNING, SubmissionStatus.FAILED],
  287. ),
  288. (
  289. [Status.SUBMITTED, Status.PENDING, Status.CANCELED],
  290. [SubmissionStatus.PENDING, SubmissionStatus.PENDING, SubmissionStatus.CANCELED],
  291. ),
  292. (
  293. [Status.SUBMITTED, Status.PENDING, Status.RUNNING, Status.CANCELED],
  294. [SubmissionStatus.PENDING, SubmissionStatus.PENDING, SubmissionStatus.RUNNING, SubmissionStatus.CANCELED],
  295. ),
  296. ([Status.SUBMITTED, Status.BLOCKED], [SubmissionStatus.PENDING, SubmissionStatus.BLOCKED]),
  297. ([Status.SUBMITTED, Status.SKIPPED], [SubmissionStatus.PENDING, SubmissionStatus.COMPLETED]),
  298. ],
  299. )
  300. def test_update_submission_status_with_single_job_completed(job_statuses, expected_submission_statuses):
  301. job = MockJob("job_id", Status.SUBMITTED)
  302. submission = Submission("submission_id", "ENTITY_TYPE", "entity_config_id")
  303. assert submission.submission_status == SubmissionStatus.SUBMITTED
  304. for job_status, submission_status in zip(job_statuses, expected_submission_statuses):
  305. job.status = job_status
  306. submission._update_submission_status(job)
  307. assert submission.submission_status == submission_status
  308. def __test_update_submission_status_with_two_jobs(job_ids, job_statuses, expected_submission_statuses):
  309. jobs = {job_id: MockJob(job_id, Status.SUBMITTED) for job_id in job_ids}
  310. submission = Submission("submission_id", "ENTITY_TYPE", "entity_config_id")
  311. assert submission.submission_status == SubmissionStatus.SUBMITTED
  312. for (job_id, job_status), submission_status in zip(job_statuses, expected_submission_statuses):
  313. job = jobs[job_id]
  314. job.status = job_status
  315. submission._update_submission_status(job)
  316. assert submission.submission_status == submission_status
  317. @pytest.mark.parametrize(
  318. "job_ids, job_statuses, expected_submission_statuses",
  319. [
  320. (
  321. ["job_1", "job_2"],
  322. [
  323. ("job_1", Status.SUBMITTED),
  324. ("job_2", Status.SUBMITTED),
  325. ("job_1", Status.PENDING),
  326. ("job_2", Status.PENDING),
  327. ("job_1", Status.RUNNING),
  328. ("job_2", Status.RUNNING),
  329. ("job_1", Status.COMPLETED),
  330. ("job_2", Status.COMPLETED),
  331. ],
  332. [
  333. SubmissionStatus.PENDING,
  334. SubmissionStatus.PENDING,
  335. SubmissionStatus.PENDING,
  336. SubmissionStatus.PENDING,
  337. SubmissionStatus.RUNNING,
  338. SubmissionStatus.RUNNING,
  339. SubmissionStatus.RUNNING,
  340. SubmissionStatus.COMPLETED,
  341. ],
  342. ),
  343. (
  344. ["job_1", "job_2"],
  345. [
  346. ("job_1", Status.SUBMITTED),
  347. ("job_2", Status.SUBMITTED),
  348. ("job_1", Status.PENDING),
  349. ("job_1", Status.RUNNING),
  350. ("job_2", Status.PENDING),
  351. ("job_2", Status.RUNNING),
  352. ("job_1", Status.COMPLETED),
  353. ("job_2", Status.COMPLETED),
  354. ],
  355. [
  356. SubmissionStatus.PENDING,
  357. SubmissionStatus.PENDING,
  358. SubmissionStatus.PENDING,
  359. SubmissionStatus.RUNNING,
  360. SubmissionStatus.RUNNING,
  361. SubmissionStatus.RUNNING,
  362. SubmissionStatus.RUNNING,
  363. SubmissionStatus.COMPLETED,
  364. ],
  365. ),
  366. (
  367. ["job_1", "job_2"],
  368. [
  369. ("job_1", Status.SUBMITTED),
  370. ("job_2", Status.SUBMITTED),
  371. ("job_1", Status.BLOCKED),
  372. ("job_2", Status.PENDING),
  373. ("job_2", Status.RUNNING),
  374. ("job_2", Status.COMPLETED),
  375. ("job_1", Status.PENDING),
  376. ("job_1", Status.RUNNING),
  377. ("job_1", Status.COMPLETED),
  378. ],
  379. [
  380. SubmissionStatus.PENDING,
  381. SubmissionStatus.PENDING,
  382. SubmissionStatus.PENDING,
  383. SubmissionStatus.PENDING,
  384. SubmissionStatus.RUNNING,
  385. SubmissionStatus.BLOCKED,
  386. SubmissionStatus.PENDING,
  387. SubmissionStatus.RUNNING,
  388. SubmissionStatus.COMPLETED,
  389. ],
  390. ),
  391. ],
  392. )
  393. def test_update_submission_status_with_two_jobs_completed(job_ids, job_statuses, expected_submission_statuses):
  394. __test_update_submission_status_with_two_jobs(job_ids, job_statuses, expected_submission_statuses)
  395. @pytest.mark.parametrize(
  396. "job_ids, job_statuses, expected_submission_statuses",
  397. [
  398. (
  399. ["job_1", "job_2"],
  400. [
  401. ("job_1", Status.SUBMITTED),
  402. ("job_2", Status.SUBMITTED),
  403. ("job_1", Status.PENDING),
  404. ("job_2", Status.PENDING),
  405. ("job_1", Status.RUNNING),
  406. ("job_2", Status.SKIPPED),
  407. ("job_1", Status.COMPLETED),
  408. ],
  409. [
  410. SubmissionStatus.PENDING,
  411. SubmissionStatus.PENDING,
  412. SubmissionStatus.PENDING,
  413. SubmissionStatus.PENDING,
  414. SubmissionStatus.RUNNING,
  415. SubmissionStatus.RUNNING,
  416. SubmissionStatus.COMPLETED,
  417. ],
  418. ),
  419. (
  420. ["job_1", "job_2"],
  421. [
  422. ("job_1", Status.SUBMITTED),
  423. ("job_2", Status.SUBMITTED),
  424. ("job_1", Status.PENDING),
  425. ("job_1", Status.RUNNING),
  426. ("job_2", Status.PENDING),
  427. ("job_2", Status.SKIPPED),
  428. ("job_1", Status.COMPLETED),
  429. ],
  430. [
  431. SubmissionStatus.PENDING,
  432. SubmissionStatus.PENDING,
  433. SubmissionStatus.PENDING,
  434. SubmissionStatus.RUNNING,
  435. SubmissionStatus.RUNNING,
  436. SubmissionStatus.RUNNING,
  437. SubmissionStatus.COMPLETED,
  438. ],
  439. ),
  440. (
  441. ["job_1", "job_2"],
  442. [
  443. ("job_1", Status.SUBMITTED),
  444. ("job_2", Status.SUBMITTED),
  445. ("job_1", Status.BLOCKED),
  446. ("job_2", Status.PENDING),
  447. ("job_2", Status.RUNNING),
  448. ("job_2", Status.COMPLETED),
  449. ("job_1", Status.PENDING),
  450. ("job_1", Status.SKIPPED),
  451. ],
  452. [
  453. SubmissionStatus.PENDING,
  454. SubmissionStatus.PENDING,
  455. SubmissionStatus.PENDING,
  456. SubmissionStatus.PENDING,
  457. SubmissionStatus.RUNNING,
  458. SubmissionStatus.BLOCKED,
  459. SubmissionStatus.PENDING,
  460. SubmissionStatus.COMPLETED,
  461. ],
  462. ),
  463. (
  464. ["job_1", "job_2"],
  465. [
  466. ("job_1", Status.SUBMITTED),
  467. ("job_2", Status.SUBMITTED),
  468. ("job_1", Status.PENDING),
  469. ("job_2", Status.PENDING),
  470. ("job_1", Status.SKIPPED),
  471. ("job_2", Status.SKIPPED),
  472. ],
  473. [
  474. SubmissionStatus.PENDING,
  475. SubmissionStatus.PENDING,
  476. SubmissionStatus.PENDING,
  477. SubmissionStatus.PENDING,
  478. SubmissionStatus.PENDING,
  479. SubmissionStatus.COMPLETED,
  480. ],
  481. ),
  482. (
  483. ["job_1", "job_2"],
  484. [
  485. ("job_1", Status.SUBMITTED),
  486. ("job_2", Status.SUBMITTED),
  487. ("job_1", Status.PENDING),
  488. ("job_1", Status.SKIPPED),
  489. ("job_2", Status.PENDING),
  490. ("job_2", Status.SKIPPED),
  491. ],
  492. [
  493. SubmissionStatus.PENDING,
  494. SubmissionStatus.PENDING,
  495. SubmissionStatus.PENDING,
  496. SubmissionStatus.PENDING,
  497. SubmissionStatus.PENDING,
  498. SubmissionStatus.COMPLETED,
  499. ],
  500. ),
  501. (
  502. ["job_1", "job_2"],
  503. [
  504. ("job_1", Status.SUBMITTED),
  505. ("job_2", Status.SUBMITTED),
  506. ("job_1", Status.BLOCKED),
  507. ("job_2", Status.PENDING),
  508. ("job_2", Status.SKIPPED),
  509. ("job_1", Status.PENDING),
  510. ("job_1", Status.SKIPPED),
  511. ],
  512. [
  513. SubmissionStatus.PENDING,
  514. SubmissionStatus.PENDING,
  515. SubmissionStatus.PENDING,
  516. SubmissionStatus.PENDING,
  517. SubmissionStatus.BLOCKED,
  518. SubmissionStatus.PENDING,
  519. SubmissionStatus.COMPLETED,
  520. ],
  521. ),
  522. ],
  523. )
  524. def test_update_submission_status_with_two_jobs_skipped(job_ids, job_statuses, expected_submission_statuses):
  525. __test_update_submission_status_with_two_jobs(job_ids, job_statuses, expected_submission_statuses)
  526. @pytest.mark.parametrize(
  527. "job_ids, job_statuses, expected_submission_statuses",
  528. [
  529. (
  530. ["job_1", "job_2"],
  531. [
  532. ("job_1", Status.SUBMITTED),
  533. ("job_2", Status.SUBMITTED),
  534. ("job_1", Status.PENDING),
  535. ("job_2", Status.PENDING),
  536. ("job_1", Status.RUNNING),
  537. ("job_2", Status.RUNNING),
  538. ("job_1", Status.FAILED),
  539. ("job_2", Status.COMPLETED),
  540. ],
  541. [
  542. SubmissionStatus.PENDING,
  543. SubmissionStatus.PENDING,
  544. SubmissionStatus.PENDING,
  545. SubmissionStatus.PENDING,
  546. SubmissionStatus.RUNNING,
  547. SubmissionStatus.RUNNING,
  548. SubmissionStatus.FAILED,
  549. SubmissionStatus.FAILED,
  550. ],
  551. ),
  552. (
  553. ["job_1", "job_2"],
  554. [
  555. ("job_1", Status.SUBMITTED),
  556. ("job_2", Status.SUBMITTED),
  557. ("job_1", Status.PENDING),
  558. ("job_1", Status.RUNNING),
  559. ("job_2", Status.PENDING),
  560. ("job_2", Status.RUNNING),
  561. ("job_1", Status.COMPLETED),
  562. ("job_2", Status.FAILED),
  563. ],
  564. [
  565. SubmissionStatus.PENDING,
  566. SubmissionStatus.PENDING,
  567. SubmissionStatus.PENDING,
  568. SubmissionStatus.RUNNING,
  569. SubmissionStatus.RUNNING,
  570. SubmissionStatus.RUNNING,
  571. SubmissionStatus.RUNNING,
  572. SubmissionStatus.FAILED,
  573. ],
  574. ),
  575. (
  576. ["job_1", "job_2"],
  577. [
  578. ("job_1", Status.SUBMITTED),
  579. ("job_2", Status.SUBMITTED),
  580. ("job_1", Status.BLOCKED),
  581. ("job_2", Status.PENDING),
  582. ("job_2", Status.RUNNING),
  583. ("job_2", Status.FAILED),
  584. ("job_1", Status.ABANDONED),
  585. ],
  586. [
  587. SubmissionStatus.PENDING,
  588. SubmissionStatus.PENDING,
  589. SubmissionStatus.PENDING,
  590. SubmissionStatus.PENDING,
  591. SubmissionStatus.RUNNING,
  592. SubmissionStatus.FAILED,
  593. SubmissionStatus.FAILED,
  594. ],
  595. ),
  596. ],
  597. )
  598. def test_update_submission_status_with_two_jobs_failed(job_ids, job_statuses, expected_submission_statuses):
  599. __test_update_submission_status_with_two_jobs(job_ids, job_statuses, expected_submission_statuses)
  600. @pytest.mark.parametrize(
  601. "job_ids, job_statuses, expected_submission_statuses",
  602. [
  603. (
  604. ["job_1", "job_2"],
  605. [
  606. ("job_1", Status.SUBMITTED),
  607. ("job_2", Status.SUBMITTED),
  608. ("job_1", Status.PENDING),
  609. ("job_2", Status.PENDING),
  610. ("job_1", Status.RUNNING),
  611. ("job_2", Status.RUNNING),
  612. ("job_1", Status.CANCELED),
  613. ("job_2", Status.COMPLETED),
  614. ],
  615. [
  616. SubmissionStatus.PENDING,
  617. SubmissionStatus.PENDING,
  618. SubmissionStatus.PENDING,
  619. SubmissionStatus.PENDING,
  620. SubmissionStatus.RUNNING,
  621. SubmissionStatus.RUNNING,
  622. SubmissionStatus.CANCELED,
  623. SubmissionStatus.CANCELED,
  624. ],
  625. ),
  626. (
  627. ["job_1", "job_2"],
  628. [
  629. ("job_1", Status.SUBMITTED),
  630. ("job_2", Status.SUBMITTED),
  631. ("job_1", Status.PENDING),
  632. ("job_1", Status.RUNNING),
  633. ("job_2", Status.PENDING),
  634. ("job_2", Status.RUNNING),
  635. ("job_1", Status.COMPLETED),
  636. ("job_2", Status.CANCELED),
  637. ],
  638. [
  639. SubmissionStatus.PENDING,
  640. SubmissionStatus.PENDING,
  641. SubmissionStatus.PENDING,
  642. SubmissionStatus.RUNNING,
  643. SubmissionStatus.RUNNING,
  644. SubmissionStatus.RUNNING,
  645. SubmissionStatus.RUNNING,
  646. SubmissionStatus.CANCELED,
  647. ],
  648. ),
  649. (
  650. ["job_1", "job_2"],
  651. [
  652. ("job_1", Status.SUBMITTED),
  653. ("job_2", Status.SUBMITTED),
  654. ("job_1", Status.BLOCKED),
  655. ("job_2", Status.PENDING),
  656. ("job_2", Status.RUNNING),
  657. ("job_2", Status.CANCELED),
  658. ("job_1", Status.ABANDONED),
  659. ],
  660. [
  661. SubmissionStatus.PENDING,
  662. SubmissionStatus.PENDING,
  663. SubmissionStatus.PENDING,
  664. SubmissionStatus.PENDING,
  665. SubmissionStatus.RUNNING,
  666. SubmissionStatus.CANCELED,
  667. SubmissionStatus.CANCELED,
  668. ],
  669. ),
  670. ],
  671. )
  672. def test_update_submission_status_with_two_jobs_canceled(job_ids, job_statuses, expected_submission_statuses):
  673. __test_update_submission_status_with_two_jobs(job_ids, job_statuses, expected_submission_statuses)
  674. def test_is_finished():
  675. submission_manager = _SubmissionManagerFactory._build_manager()
  676. submission = Submission("entity_id", "entity_type", "entity_config_id", "submission_id")
  677. submission_manager._set(submission)
  678. assert len(submission_manager._get_all()) == 1
  679. assert submission._submission_status == SubmissionStatus.SUBMITTED
  680. assert not submission.is_finished()
  681. submission.submission_status = SubmissionStatus.UNDEFINED
  682. assert submission.submission_status == SubmissionStatus.UNDEFINED
  683. assert not submission.is_finished()
  684. submission.submission_status = SubmissionStatus.CANCELED
  685. assert submission.submission_status == SubmissionStatus.CANCELED
  686. assert submission.is_finished()
  687. submission.submission_status = SubmissionStatus.FAILED
  688. assert submission.submission_status == SubmissionStatus.FAILED
  689. assert submission.is_finished()
  690. submission.submission_status = SubmissionStatus.BLOCKED
  691. assert submission.submission_status == SubmissionStatus.BLOCKED
  692. assert not submission.is_finished()
  693. submission.submission_status = SubmissionStatus.RUNNING
  694. assert submission.submission_status == SubmissionStatus.RUNNING
  695. assert not submission.is_finished()
  696. submission.submission_status = SubmissionStatus.PENDING
  697. assert submission.submission_status == SubmissionStatus.PENDING
  698. assert not submission.is_finished()
  699. submission.submission_status = SubmissionStatus.COMPLETED
  700. assert submission.submission_status == SubmissionStatus.COMPLETED
  701. assert submission.is_finished()