test_notifier.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  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 queue import SimpleQueue
  12. from taipy.config import Config, Frequency
  13. from taipy.core import taipy as tp
  14. from taipy.core._version._version_manager_factory import _VersionManagerFactory
  15. from taipy.core.notification import EventEntityType, EventOperation
  16. from taipy.core.notification._topic import _Topic
  17. from taipy.core.notification.event import Event
  18. from taipy.core.notification.notifier import Notifier
  19. from taipy.core.scenario._scenario_manager_factory import _ScenarioManagerFactory
  20. def test_register():
  21. def find_registration_and_topic(registration_id):
  22. for topic, registrations in Notifier._topics_registrations_list.items():
  23. for registration in registrations:
  24. if registration.registration_id == registration_id:
  25. return topic, registration
  26. assert len(Notifier._topics_registrations_list) == 0
  27. registration_id_0, register_queue_0 = Notifier.register()
  28. topic_0, registration_0 = find_registration_and_topic(registration_id_0)
  29. assert isinstance(registration_id_0, str) and registration_id_0 == registration_0.registration_id
  30. assert isinstance(register_queue_0, SimpleQueue)
  31. assert len(Notifier._topics_registrations_list.keys()) == 1
  32. assert len(Notifier._topics_registrations_list[topic_0]) == 1
  33. assert registration_0.queue == register_queue_0
  34. assert register_queue_0 in [registration.queue for registration in Notifier._topics_registrations_list[topic_0]]
  35. registration_id_1, register_queue_1 = Notifier.register()
  36. topic_1, registration_1 = find_registration_and_topic(registration_id_1)
  37. assert isinstance(registration_id_1, str) and registration_id_1 == registration_1.registration_id
  38. assert isinstance(register_queue_1, SimpleQueue)
  39. assert len(Notifier._topics_registrations_list.keys()) == 1
  40. assert len(Notifier._topics_registrations_list[topic_1]) == 2
  41. assert registration_1.queue == register_queue_1
  42. assert register_queue_1 in [registration.queue for registration in Notifier._topics_registrations_list[topic_1]]
  43. registration_id_2, register_queue_2 = Notifier.register(EventEntityType.SCENARIO)
  44. topic_2, registration_2 = find_registration_and_topic(registration_id_2)
  45. assert isinstance(registration_id_2, str) and registration_id_2 == registration_2.registration_id
  46. assert isinstance(register_queue_2, SimpleQueue)
  47. assert len(Notifier._topics_registrations_list.keys()) == 2
  48. assert len(Notifier._topics_registrations_list[topic_2]) == 1
  49. assert registration_2.queue == register_queue_2
  50. assert register_queue_2 in [registration.queue for registration in Notifier._topics_registrations_list[topic_2]]
  51. registration_id_3, register_queue_3 = Notifier.register(EventEntityType.SCENARIO, "scenario_id")
  52. topic_3, registration_3 = find_registration_and_topic(registration_id_3)
  53. assert isinstance(registration_id_3, str) and registration_id_3 == registration_3.registration_id
  54. assert isinstance(register_queue_3, SimpleQueue)
  55. assert len(Notifier._topics_registrations_list.keys()) == 3
  56. assert len(Notifier._topics_registrations_list[topic_3]) == 1
  57. assert registration_3.queue == register_queue_3
  58. assert register_queue_3 in [registration.queue for registration in Notifier._topics_registrations_list[topic_3]]
  59. registration_id_4, register_queue_4 = Notifier.register(
  60. EventEntityType.SEQUENCE, "sequence_id", EventOperation.UPDATE, "tasks"
  61. )
  62. topic_4, registration_4 = find_registration_and_topic(registration_id_4)
  63. assert isinstance(registration_id_4, str) and registration_id_4 == registration_4.registration_id
  64. assert isinstance(register_queue_4, SimpleQueue)
  65. assert len(Notifier._topics_registrations_list.keys()) == 4
  66. assert len(Notifier._topics_registrations_list[topic_4]) == 1
  67. assert registration_4.queue == register_queue_4
  68. assert register_queue_4 in [registration.queue for registration in Notifier._topics_registrations_list[topic_4]]
  69. registration_id_5, register_queue_5 = Notifier.register(EventEntityType.SCENARIO)
  70. topic_5, registration_5 = find_registration_and_topic(registration_id_5)
  71. assert isinstance(registration_id_5, str) and registration_id_5 == registration_5.registration_id
  72. assert isinstance(register_queue_5, SimpleQueue)
  73. assert len(Notifier._topics_registrations_list.keys()) == 4
  74. assert len(Notifier._topics_registrations_list[topic_5]) == 2
  75. assert registration_5.queue == register_queue_5
  76. assert register_queue_5 in [registration.queue for registration in Notifier._topics_registrations_list[topic_5]]
  77. registration_id_6, register_queue_6 = Notifier.register()
  78. assert len(Notifier._topics_registrations_list.keys()) == 4
  79. assert len(Notifier._topics_registrations_list[topic_0]) == 3
  80. Notifier.unregister(registration_id_6)
  81. assert len(Notifier._topics_registrations_list.keys()) == 4
  82. assert len(Notifier._topics_registrations_list[topic_0]) == 2
  83. Notifier.unregister(registration_id_4)
  84. assert len(Notifier._topics_registrations_list.keys()) == 3
  85. assert topic_4 not in Notifier._topics_registrations_list.keys()
  86. Notifier.unregister(registration_id_0)
  87. assert len(Notifier._topics_registrations_list.keys()) == 3
  88. assert len(Notifier._topics_registrations_list[topic_0]) == 1
  89. Notifier.unregister(registration_id_1)
  90. assert len(Notifier._topics_registrations_list.keys()) == 2
  91. assert all(topic not in Notifier._topics_registrations_list.keys() for topic in [topic_0, topic_1])
  92. Notifier.unregister(registration_id_2)
  93. Notifier.unregister(registration_id_3)
  94. Notifier.unregister(registration_id_5)
  95. assert len(Notifier._topics_registrations_list.keys()) == 0
  96. def test_matching():
  97. assert Notifier._is_matching(
  98. Event(entity_type=EventEntityType.CYCLE, entity_id="cycle_id", operation=EventOperation.CREATION), _Topic()
  99. )
  100. assert Notifier._is_matching(
  101. Event(entity_type=EventEntityType.CYCLE, entity_id="cycle_id", operation=EventOperation.CREATION),
  102. _Topic(EventEntityType.CYCLE),
  103. )
  104. assert Notifier._is_matching(
  105. Event(entity_type=EventEntityType.CYCLE, entity_id="cycle_id", operation=EventOperation.CREATION),
  106. _Topic(EventEntityType.CYCLE, "cycle_id"),
  107. )
  108. assert Notifier._is_matching(
  109. Event(entity_type=EventEntityType.CYCLE, entity_id="cycle_id", operation=EventOperation.CREATION),
  110. _Topic(operation=EventOperation.CREATION),
  111. )
  112. assert Notifier._is_matching(
  113. Event(entity_type=EventEntityType.CYCLE, entity_id="cycle_id", operation=EventOperation.CREATION),
  114. _Topic(EventEntityType.CYCLE, "cycle_id", EventOperation.CREATION),
  115. )
  116. assert Notifier._is_matching(
  117. Event(entity_type=EventEntityType.SCENARIO, entity_id="scenario_id", operation=EventOperation.SUBMISSION),
  118. _Topic(),
  119. )
  120. assert Notifier._is_matching(
  121. Event(entity_type=EventEntityType.SCENARIO, entity_id="scenario_id", operation=EventOperation.SUBMISSION),
  122. _Topic(EventEntityType.SCENARIO),
  123. )
  124. assert Notifier._is_matching(
  125. Event(entity_type=EventEntityType.SCENARIO, entity_id="scenario_id", operation=EventOperation.SUBMISSION),
  126. _Topic(
  127. EventEntityType.SCENARIO,
  128. "scenario_id",
  129. ),
  130. )
  131. assert Notifier._is_matching(
  132. Event(entity_type=EventEntityType.SCENARIO, entity_id="scenario_id", operation=EventOperation.SUBMISSION),
  133. _Topic(operation=EventOperation.SUBMISSION),
  134. )
  135. assert Notifier._is_matching(
  136. Event(entity_type=EventEntityType.SCENARIO, entity_id="scenario_id", operation=EventOperation.SUBMISSION),
  137. _Topic(EventEntityType.SCENARIO, "scenario_id", EventOperation.SUBMISSION),
  138. )
  139. assert Notifier._is_matching(
  140. Event(
  141. entity_type=EventEntityType.SEQUENCE,
  142. entity_id="sequence_id",
  143. operation=EventOperation.UPDATE,
  144. attribute_name=r"tasks",
  145. ),
  146. _Topic(),
  147. )
  148. assert Notifier._is_matching(
  149. Event(
  150. entity_type=EventEntityType.SEQUENCE,
  151. entity_id="sequence_id",
  152. operation=EventOperation.UPDATE,
  153. attribute_name="tasks",
  154. ),
  155. _Topic(EventEntityType.SEQUENCE),
  156. )
  157. assert Notifier._is_matching(
  158. Event(
  159. entity_type=EventEntityType.SEQUENCE,
  160. entity_id="sequence_id",
  161. operation=EventOperation.UPDATE,
  162. attribute_name="tasks",
  163. ),
  164. _Topic(
  165. EventEntityType.SEQUENCE,
  166. "sequence_id",
  167. ),
  168. )
  169. assert Notifier._is_matching(
  170. Event(
  171. entity_type=EventEntityType.SEQUENCE,
  172. entity_id="sequence_id",
  173. operation=EventOperation.UPDATE,
  174. attribute_name="tasks",
  175. ),
  176. _Topic(operation=EventOperation.UPDATE),
  177. )
  178. assert Notifier._is_matching(
  179. Event(
  180. entity_type=EventEntityType.SEQUENCE,
  181. entity_id="sequence_id",
  182. operation=EventOperation.UPDATE,
  183. attribute_name="tasks",
  184. ),
  185. _Topic(EventEntityType.SEQUENCE, "sequence_id", EventOperation.UPDATE),
  186. )
  187. assert Notifier._is_matching(
  188. Event(
  189. entity_type=EventEntityType.SEQUENCE,
  190. entity_id="sequence_id",
  191. operation=EventOperation.UPDATE,
  192. attribute_name="tasks",
  193. ),
  194. _Topic(attribute_name="tasks"),
  195. )
  196. assert Notifier._is_matching(
  197. Event(
  198. entity_type=EventEntityType.SEQUENCE,
  199. entity_id="sequence_id",
  200. operation=EventOperation.UPDATE,
  201. attribute_name="tasks",
  202. ),
  203. _Topic(EventEntityType.SEQUENCE, attribute_name="tasks"),
  204. )
  205. assert Notifier._is_matching(
  206. Event(
  207. entity_type=EventEntityType.SEQUENCE,
  208. entity_id="sequence_id",
  209. operation=EventOperation.UPDATE,
  210. attribute_name="tasks",
  211. ),
  212. _Topic(operation=EventOperation.UPDATE, attribute_name="tasks"),
  213. )
  214. assert Notifier._is_matching(
  215. Event(
  216. entity_type=EventEntityType.SEQUENCE,
  217. entity_id="sequence_id",
  218. operation=EventOperation.UPDATE,
  219. attribute_name="tasks",
  220. ),
  221. _Topic(EventEntityType.SEQUENCE, "sequence_id", EventOperation.UPDATE, "tasks"),
  222. )
  223. assert Notifier._is_matching(Event(EventEntityType.TASK, "task_id", EventOperation.DELETION), _Topic())
  224. assert Notifier._is_matching(
  225. Event(EventEntityType.TASK, "task_id", EventOperation.DELETION), _Topic(EventEntityType.TASK)
  226. )
  227. assert Notifier._is_matching(
  228. Event(entity_type=EventEntityType.TASK, entity_id="task_id", operation=EventOperation.DELETION),
  229. _Topic(
  230. EventEntityType.TASK,
  231. "task_id",
  232. ),
  233. )
  234. assert Notifier._is_matching(
  235. Event(entity_type=EventEntityType.TASK, entity_id="task_id", operation=EventOperation.DELETION),
  236. _Topic(operation=EventOperation.DELETION),
  237. )
  238. assert Notifier._is_matching(
  239. Event(entity_type=EventEntityType.TASK, entity_id="task_id", operation=EventOperation.DELETION),
  240. _Topic(EventEntityType.TASK, "task_id", EventOperation.DELETION),
  241. )
  242. assert not Notifier._is_matching(
  243. Event(entity_type=EventEntityType.DATA_NODE, entity_id="dn_id", operation=EventOperation.CREATION),
  244. _Topic(EventEntityType.CYCLE),
  245. )
  246. assert not Notifier._is_matching(
  247. Event(entity_type=EventEntityType.DATA_NODE, entity_id="dn_id", operation=EventOperation.CREATION),
  248. _Topic(EventEntityType.SCENARIO, "scenario_id"),
  249. )
  250. assert not Notifier._is_matching(
  251. Event(entity_type=EventEntityType.DATA_NODE, entity_id="dn_id", operation=EventOperation.CREATION),
  252. _Topic(EventEntityType.TASK, "task_id", EventOperation.CREATION),
  253. )
  254. assert not Notifier._is_matching(
  255. Event(entity_type=EventEntityType.JOB, entity_id="job_id", operation=EventOperation.DELETION),
  256. _Topic(EventEntityType.JOB, "job_id", EventOperation.CREATION),
  257. )
  258. assert not Notifier._is_matching(
  259. Event(entity_type=EventEntityType.JOB, entity_id="job_id", operation=EventOperation.DELETION),
  260. _Topic(EventEntityType.JOB, "job_id_1", EventOperation.DELETION),
  261. )
  262. assert not Notifier._is_matching(
  263. Event(
  264. entity_type=EventEntityType.JOB,
  265. entity_id="job_id",
  266. operation=EventOperation.UPDATE,
  267. attribute_name="status",
  268. ),
  269. _Topic(EventEntityType.JOB, "job_id", EventOperation.UPDATE, "submit_id"),
  270. )
  271. assert not Notifier._is_matching(
  272. Event(
  273. entity_type=EventEntityType.JOB,
  274. entity_id="job_id",
  275. operation=EventOperation.UPDATE,
  276. attribute_name="status",
  277. ),
  278. _Topic(operation=EventOperation.UPDATE, attribute_name="submit_id"),
  279. )
  280. def test_publish_creation_event():
  281. _, registration_queue = Notifier.register()
  282. dn_config = Config.configure_data_node("dn_config")
  283. task_config = Config.configure_task("task_config", print, [dn_config])
  284. scenario_config = Config.configure_scenario(
  285. "scenario_config", [task_config], frequency=Frequency.DAILY, flag="test"
  286. )
  287. scenario_config.add_sequences({"sequence_config": [task_config]})
  288. # Test CREATION Event
  289. scenario = _ScenarioManagerFactory._build_manager()._create(scenario_config)
  290. cycle = scenario.cycle
  291. task = scenario.tasks[task_config.id]
  292. dn = scenario.data_nodes[dn_config.id]
  293. sequence = scenario.sequences["sequence_config"]
  294. assert registration_queue.qsize() == 5
  295. published_events = []
  296. while registration_queue.qsize() != 0:
  297. published_events.append(registration_queue.get())
  298. expected_event_types = [
  299. EventEntityType.CYCLE,
  300. EventEntityType.DATA_NODE,
  301. EventEntityType.TASK,
  302. EventEntityType.SEQUENCE,
  303. EventEntityType.SCENARIO,
  304. ]
  305. expected_event_entity_id = [cycle.id, dn.id, task.id, sequence.id, scenario.id]
  306. assert all(
  307. event.entity_type == expected_event_types[i]
  308. and event.entity_id == expected_event_entity_id[i]
  309. and event.operation == EventOperation.CREATION
  310. and event.attribute_name is None
  311. for i, event in enumerate(published_events)
  312. )
  313. def test_publish_update_event():
  314. _, registration_queue = Notifier.register()
  315. dn_config = Config.configure_data_node("dn_config")
  316. task_config = Config.configure_task("task_config", print, [dn_config])
  317. scenario_config = Config.configure_scenario(
  318. "scenario_config", [task_config], frequency=Frequency.DAILY, flag="test"
  319. )
  320. scenario_config.add_sequences({"sequence_config": [task_config]})
  321. scenario = _ScenarioManagerFactory._build_manager()._create(scenario_config)
  322. cycle = scenario.cycle
  323. task = scenario.tasks[task_config.id]
  324. dn = scenario.data_nodes[dn_config.id]
  325. sequence = scenario.sequences["sequence_config"]
  326. assert registration_queue.qsize() == 5
  327. while registration_queue.qsize() > 0:
  328. registration_queue.get()
  329. # Test UPDATE Event
  330. scenario.is_primary = False
  331. assert registration_queue.qsize() == 1
  332. tp.set_primary(scenario)
  333. assert registration_queue.qsize() == 2
  334. tp.subscribe_scenario(print, None, scenario=scenario)
  335. assert registration_queue.qsize() == 3
  336. tp.unsubscribe_scenario(print, None, scenario=scenario)
  337. assert registration_queue.qsize() == 4
  338. tp.tag(scenario, "testing")
  339. assert registration_queue.qsize() == 5
  340. tp.untag(scenario, "testing")
  341. assert registration_queue.qsize() == 6
  342. scenario.properties["flag"] = "production"
  343. assert registration_queue.qsize() == 7
  344. scenario.properties.update({"description": "a scenario", "test_mult": True})
  345. assert registration_queue.qsize() == 9
  346. scenario.properties.pop("test_mult")
  347. assert registration_queue.qsize() == 10
  348. scenario.name = "my_scenario"
  349. assert registration_queue.qsize() == 11
  350. cycle.name = "new cycle name"
  351. assert registration_queue.qsize() == 12
  352. cycle.properties["valid"] = True
  353. assert registration_queue.qsize() == 13
  354. cycle.properties.update({"re_run_periodically": True})
  355. assert registration_queue.qsize() == 14
  356. cycle.properties.pop("re_run_periodically")
  357. assert registration_queue.qsize() == 15
  358. sequence.properties["name"] = "weather_forecast"
  359. assert registration_queue.qsize() == 16
  360. tp.subscribe_sequence(print, None, sequence)
  361. assert registration_queue.qsize() == 17
  362. tp.unsubscribe_sequence(print, None, sequence)
  363. assert registration_queue.qsize() == 18
  364. task.skippable = True
  365. assert registration_queue.qsize() == 19
  366. task.properties["number_of_run"] = 2
  367. assert registration_queue.qsize() == 20
  368. task.properties.update({"debug": True})
  369. assert registration_queue.qsize() == 21
  370. task.properties.pop("debug")
  371. assert registration_queue.qsize() == 22
  372. dn.editor_id = "new editor id"
  373. assert registration_queue.qsize() == 23
  374. dn.properties["sorted"] = True
  375. assert registration_queue.qsize() == 24
  376. dn.properties.update({"only_fetch_first_100": True})
  377. assert registration_queue.qsize() == 25
  378. dn.properties.pop("only_fetch_first_100")
  379. assert registration_queue.qsize() == 26
  380. published_events = []
  381. while registration_queue.qsize() != 0:
  382. published_events.append(registration_queue.get())
  383. expected_event_types = [
  384. EventEntityType.SCENARIO,
  385. EventEntityType.SCENARIO,
  386. EventEntityType.SCENARIO,
  387. EventEntityType.SCENARIO,
  388. EventEntityType.SCENARIO,
  389. EventEntityType.SCENARIO,
  390. EventEntityType.SCENARIO,
  391. EventEntityType.SCENARIO,
  392. EventEntityType.SCENARIO,
  393. EventEntityType.SCENARIO,
  394. EventEntityType.SCENARIO,
  395. EventEntityType.CYCLE,
  396. EventEntityType.CYCLE,
  397. EventEntityType.CYCLE,
  398. EventEntityType.CYCLE,
  399. EventEntityType.SEQUENCE,
  400. EventEntityType.SEQUENCE,
  401. EventEntityType.SEQUENCE,
  402. EventEntityType.TASK,
  403. EventEntityType.TASK,
  404. EventEntityType.TASK,
  405. EventEntityType.TASK,
  406. EventEntityType.DATA_NODE,
  407. EventEntityType.DATA_NODE,
  408. EventEntityType.DATA_NODE,
  409. EventEntityType.DATA_NODE,
  410. ]
  411. expected_attribute_names = [
  412. "is_primary",
  413. "is_primary",
  414. "subscribers",
  415. "subscribers",
  416. "tags",
  417. "tags",
  418. "properties",
  419. "properties",
  420. "properties",
  421. "properties",
  422. "properties",
  423. "name",
  424. "properties",
  425. "properties",
  426. "properties",
  427. "properties",
  428. "subscribers",
  429. "subscribers",
  430. "skippable",
  431. "properties",
  432. "properties",
  433. "properties",
  434. "editor_id",
  435. "properties",
  436. "properties",
  437. "properties",
  438. ]
  439. expected_event_entity_id = [
  440. scenario.id,
  441. scenario.id,
  442. scenario.id,
  443. scenario.id,
  444. scenario.id,
  445. scenario.id,
  446. scenario.id,
  447. scenario.id,
  448. scenario.id,
  449. scenario.id,
  450. scenario.id,
  451. cycle.id,
  452. cycle.id,
  453. cycle.id,
  454. cycle.id,
  455. sequence.id,
  456. sequence.id,
  457. sequence.id,
  458. task.id,
  459. task.id,
  460. task.id,
  461. task.id,
  462. dn.id,
  463. dn.id,
  464. dn.id,
  465. dn.id,
  466. ]
  467. expected_event_operation_type = [EventOperation.UPDATE] * len(expected_event_types)
  468. assert all(
  469. event.entity_type == expected_event_types[i]
  470. and event.entity_id == expected_event_entity_id[i]
  471. and event.operation == expected_event_operation_type[i]
  472. and event.attribute_name == expected_attribute_names[i]
  473. for i, event in enumerate(published_events)
  474. )
  475. def test_publish_update_event_in_context_manager():
  476. _, registration_queue = Notifier.register()
  477. dn_config = Config.configure_data_node("dn_config")
  478. task_config = Config.configure_task("task_config", print, [dn_config])
  479. scenario_config = Config.configure_scenario(
  480. "scenario_config", [task_config], frequency=Frequency.DAILY, flag="test"
  481. )
  482. scenario_config.add_sequences({"sequence_config": [task_config]})
  483. scenario = _ScenarioManagerFactory._build_manager()._create(scenario_config)
  484. cycle = scenario.cycle
  485. task = scenario.tasks[task_config.id]
  486. dn = scenario.data_nodes[dn_config.id]
  487. sequence = scenario.sequences["sequence_config"]
  488. scenario.properties.update({"description": "a scenario"})
  489. assert registration_queue.qsize() == 6
  490. while registration_queue.qsize() > 0:
  491. registration_queue.get()
  492. # Test UPDATE Event in Context Manager
  493. assert registration_queue.qsize() == 0
  494. # If multiple entities is in context, the last to enter will be the first to exit
  495. # So the published event will have the order starting with scenario first and ending with dn
  496. with dn as d, task as t, sequence as s, cycle as c, scenario as sc:
  497. sc.is_primary = True
  498. assert registration_queue.qsize() == 0
  499. tp.set_primary(sc)
  500. assert registration_queue.qsize() == 0
  501. sc.properties["flag"] = "production"
  502. assert registration_queue.qsize() == 0
  503. sc.properties.update({"description": "a scenario"})
  504. assert registration_queue.qsize() == 0
  505. sc.properties.pop("description")
  506. assert registration_queue.qsize() == 0
  507. sc.name = "my_scenario"
  508. assert registration_queue.qsize() == 0
  509. c.name = "another new cycle name"
  510. assert registration_queue.qsize() == 0
  511. c.properties["valid"] = True
  512. assert registration_queue.qsize() == 0
  513. c.properties.update({"re_run_periodically": True})
  514. assert registration_queue.qsize() == 0
  515. s.properties["name"] = "weather_forecast"
  516. assert registration_queue.qsize() == 0
  517. t.skippable = True
  518. assert registration_queue.qsize() == 0
  519. t.properties["number_of_run"] = 2
  520. assert registration_queue.qsize() == 0
  521. t.properties.update({"debug": True})
  522. assert registration_queue.qsize() == 0
  523. d.editor_id = "another new editor id"
  524. assert registration_queue.qsize() == 0
  525. d.properties["sorted"] = True
  526. assert registration_queue.qsize() == 0
  527. d.properties.update({"only_fetch_first_100": True})
  528. assert registration_queue.qsize() == 0
  529. published_events = []
  530. assert registration_queue.qsize() == 16
  531. while registration_queue.qsize() != 0:
  532. published_events.append(registration_queue.get())
  533. expected_event_types = [
  534. EventEntityType.SCENARIO,
  535. EventEntityType.SCENARIO,
  536. EventEntityType.SCENARIO,
  537. EventEntityType.SCENARIO,
  538. EventEntityType.SCENARIO,
  539. EventEntityType.SCENARIO,
  540. EventEntityType.CYCLE,
  541. EventEntityType.CYCLE,
  542. EventEntityType.CYCLE,
  543. EventEntityType.SEQUENCE,
  544. EventEntityType.TASK,
  545. EventEntityType.TASK,
  546. EventEntityType.TASK,
  547. EventEntityType.DATA_NODE,
  548. EventEntityType.DATA_NODE,
  549. EventEntityType.DATA_NODE,
  550. ]
  551. expected_attribute_names = [
  552. "is_primary",
  553. "is_primary",
  554. "properties",
  555. "properties",
  556. "properties",
  557. "properties",
  558. "name",
  559. "properties",
  560. "properties",
  561. "properties",
  562. "skippable",
  563. "properties",
  564. "properties",
  565. "editor_id",
  566. "properties",
  567. "properties",
  568. ]
  569. expected_event_entity_id = [
  570. scenario.id,
  571. scenario.id,
  572. scenario.id,
  573. scenario.id,
  574. scenario.id,
  575. scenario.id,
  576. cycle.id,
  577. cycle.id,
  578. cycle.id,
  579. sequence.id,
  580. task.id,
  581. task.id,
  582. task.id,
  583. dn.id,
  584. dn.id,
  585. dn.id,
  586. ]
  587. assert all(
  588. event.entity_type == expected_event_types[i]
  589. and event.entity_id == expected_event_entity_id[i]
  590. and event.operation == EventOperation.UPDATE
  591. and event.attribute_name == expected_attribute_names[i]
  592. for i, event in enumerate(published_events)
  593. )
  594. def test_publish_submission_event():
  595. _, registration_queue = Notifier.register()
  596. dn_config = Config.configure_data_node("dn_config")
  597. task_config = Config.configure_task("task_config", print, [dn_config])
  598. scenario_config = Config.configure_scenario(
  599. "scenario_config", [task_config], frequency=Frequency.DAILY, flag="test"
  600. )
  601. scenario_config.add_sequences({"sequence_config": [task_config]})
  602. scenario = _ScenarioManagerFactory._build_manager()._create(scenario_config)
  603. assert registration_queue.qsize() == 5
  604. while registration_queue.qsize() > 0:
  605. registration_queue.get()
  606. # Test SUBMISSION Event
  607. submission = scenario.submit()
  608. job = submission.jobs[0]
  609. assert registration_queue.qsize() == 6
  610. published_events = []
  611. while registration_queue.qsize() != 0:
  612. published_events.append(registration_queue.get())
  613. expected_operations = [
  614. EventOperation.CREATION,
  615. EventOperation.CREATION,
  616. EventOperation.UPDATE,
  617. EventOperation.UPDATE,
  618. EventOperation.UPDATE,
  619. EventOperation.SUBMISSION,
  620. ]
  621. expected_attribute_names = [None, None, "jobs", "status", "submission_status", None]
  622. expected_event_types = [
  623. EventEntityType.SUBMISSION,
  624. EventEntityType.JOB,
  625. EventEntityType.SUBMISSION,
  626. EventEntityType.JOB,
  627. EventEntityType.SUBMISSION,
  628. EventEntityType.SCENARIO,
  629. ]
  630. expected_event_entity_id = [submission.id, job.id, submission.id, job.id, submission.id, scenario.id]
  631. assert all(
  632. event.entity_type == expected_event_types[i]
  633. and event.entity_id == expected_event_entity_id[i]
  634. and event.operation == expected_operations[i]
  635. and event.attribute_name == expected_attribute_names[i]
  636. for i, event in enumerate(published_events)
  637. )
  638. def test_publish_deletion_event():
  639. _, registration_queue = Notifier.register()
  640. dn_config = Config.configure_data_node("dn_config")
  641. task_config = Config.configure_task("task_config", print, [dn_config])
  642. scenario_config = Config.configure_scenario(
  643. "scenario_config", [task_config], frequency=Frequency.DAILY, flag="test"
  644. )
  645. scenario_config.add_sequences({"sequence_config": [task_config]})
  646. scenario = _ScenarioManagerFactory._build_manager()._create(scenario_config)
  647. cycle = scenario.cycle
  648. task = scenario.tasks[task_config.id]
  649. dn = scenario.data_nodes[dn_config.id]
  650. sequence = scenario.sequences["sequence_config"]
  651. submission = scenario.submit()
  652. job = submission.jobs[0]
  653. assert registration_queue.qsize() == 11
  654. while registration_queue.qsize() > 0:
  655. registration_queue.get()
  656. # Test DELETION Event
  657. tp.delete(scenario.id)
  658. assert registration_queue.qsize() == 7
  659. published_events = []
  660. while registration_queue.qsize() != 0:
  661. published_events.append(registration_queue.get())
  662. expected_event_types = [
  663. EventEntityType.CYCLE,
  664. EventEntityType.SEQUENCE,
  665. EventEntityType.SCENARIO,
  666. EventEntityType.TASK,
  667. EventEntityType.JOB,
  668. EventEntityType.DATA_NODE,
  669. EventEntityType.SUBMISSION,
  670. ]
  671. expected_event_entity_id = [cycle.id, sequence.id, scenario.id, task.id, job.id, dn.id, submission.id]
  672. expected_event_operation_type = [EventOperation.DELETION] * len(expected_event_types)
  673. assert all(
  674. event.entity_type == expected_event_types[i]
  675. and event.entity_id == expected_event_entity_id[i]
  676. and event.operation == expected_event_operation_type[i]
  677. and event.attribute_name is None
  678. for i, event in enumerate(published_events)
  679. )
  680. scenario = _ScenarioManagerFactory._build_manager()._create(scenario_config)
  681. cycle = scenario.cycle
  682. assert registration_queue.qsize() == 5
  683. # only to clear the queue
  684. while registration_queue.qsize() != 0:
  685. registration_queue.get()
  686. tp.clean_all_entities(_VersionManagerFactory._build_manager()._get_latest_version())
  687. assert registration_queue.qsize() == 6
  688. published_events = []
  689. while registration_queue.qsize() != 0:
  690. published_events.append(registration_queue.get())
  691. expected_event_types = [
  692. EventEntityType.JOB,
  693. EventEntityType.SUBMISSION,
  694. EventEntityType.CYCLE,
  695. EventEntityType.SCENARIO,
  696. EventEntityType.TASK,
  697. EventEntityType.DATA_NODE,
  698. ]
  699. expected_event_entity_id = [None, None, cycle.id, scenario.id, None, None]
  700. assert all(
  701. event.entity_type == expected_event_types[i]
  702. and event.entity_id == expected_event_entity_id[i]
  703. and event.operation == EventOperation.DELETION
  704. and event.attribute_name is None
  705. for i, event in enumerate(published_events)
  706. )