conftest.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. # Copyright 2021-2025 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. import os
  12. import shutil
  13. import uuid
  14. from datetime import datetime, timedelta
  15. from queue import Queue
  16. import pandas as pd
  17. import pytest
  18. from dotenv import load_dotenv
  19. from taipy.common.config import Config
  20. from taipy.common.config.checker._checker import _Checker
  21. from taipy.core import Cycle, DataNodeId, Job, JobId, Scenario, Sequence, Task
  22. from taipy.core._orchestrator._orchestrator_factory import _OrchestratorFactory
  23. from taipy.core.common.frequency import Frequency
  24. from taipy.core.common.scope import Scope
  25. from taipy.core.cycle._cycle_manager import _CycleManager
  26. from taipy.core.data.pickle import PickleDataNode
  27. from taipy.core.job._job_manager import _JobManager
  28. from taipy.core.task._task_manager import _TaskManager
  29. from taipy.rest.app import create_app
  30. from taipy.rest.config import _RestConfigChecker
  31. from .setup.shared.algorithms import evaluate, forecast
  32. @pytest.fixture
  33. def setup_end_to_end():
  34. model_cfg = Config.configure_data_node("model", path="setup/my_model.p", storage_type="pickle")
  35. day_cfg = Config.configure_data_node(id="day")
  36. forecasts_cfg = Config.configure_data_node(id="forecasts")
  37. forecast_task_cfg = Config.configure_task(
  38. id="forecast_task",
  39. input=[model_cfg, day_cfg],
  40. function=forecast,
  41. output=forecasts_cfg,
  42. )
  43. historical_temperature_cfg = Config.configure_data_node(
  44. "historical_temperature",
  45. storage_type="csv",
  46. path="setup/historical_temperature.csv",
  47. has_header=True,
  48. )
  49. evaluation_cfg = Config.configure_data_node("evaluation")
  50. evaluate_task_cfg = Config.configure_task(
  51. "evaluate_task",
  52. input=[historical_temperature_cfg, forecasts_cfg, day_cfg],
  53. function=evaluate,
  54. output=evaluation_cfg,
  55. )
  56. scenario_config = Config.configure_scenario(
  57. "scenario", [forecast_task_cfg, evaluate_task_cfg], frequency=Frequency.DAILY
  58. )
  59. scenario_config.add_sequences({"sequence": [forecast_task_cfg, evaluate_task_cfg]})
  60. @pytest.fixture()
  61. def app():
  62. load_dotenv(".testenv")
  63. app = create_app(testing=True)
  64. app.config.update(
  65. {
  66. "TESTING": True,
  67. }
  68. )
  69. with app.app_context(), app.test_request_context():
  70. yield app
  71. @pytest.fixture()
  72. def client(app):
  73. return app.test_client()
  74. @pytest.fixture
  75. def datanode_data():
  76. return {
  77. "name": "foo",
  78. "storage_type": "in_memory",
  79. "scope": "scenario",
  80. "default_data": ["1991-01-01T00:00:00"],
  81. }
  82. @pytest.fixture
  83. def task_data():
  84. return {
  85. "config_id": "foo",
  86. "input_ids": ["DATASOURCE_foo_3b888e17-1974-4a56-a42c-c7c96bc9cd54"],
  87. "function_name": "print",
  88. "function_module": "builtins",
  89. "output_ids": ["DATASOURCE_foo_4d9923b8-eb9f-4f3c-8055-3a1ce8bee309"],
  90. }
  91. @pytest.fixture
  92. def sequence_data():
  93. return {
  94. "name": "foo",
  95. "task_ids": ["TASK_foo_3b888e17-1974-4a56-a42c-c7c96bc9cd54"],
  96. }
  97. @pytest.fixture
  98. def scenario_data():
  99. return {
  100. "name": "foo",
  101. "sequence_ids": ["SEQUENCE_foo_3b888e17-1974-4a56-a42c-c7c96bc9cd54"],
  102. "properties": {},
  103. }
  104. @pytest.fixture
  105. def default_datanode():
  106. return PickleDataNode(
  107. "input_ds",
  108. Scope.SCENARIO,
  109. DataNodeId("f"),
  110. "owner_id",
  111. None,
  112. properties={"default_data": [1, 2, 3, 4, 5, 6]},
  113. )
  114. @pytest.fixture
  115. def default_df_datanode():
  116. return PickleDataNode(
  117. "input_ds",
  118. Scope.SCENARIO,
  119. DataNodeId("id_uio2"),
  120. "owner_id",
  121. None,
  122. properties={"default_data": pd.DataFrame([{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}])},
  123. )
  124. @pytest.fixture
  125. def default_datanode_config():
  126. return Config.configure_data_node(f"taipy_{uuid.uuid4().hex}", "in_memory", Scope.SCENARIO)
  127. @pytest.fixture
  128. def default_datanode_config_list():
  129. configs = []
  130. for i in range(10):
  131. configs.append(Config.configure_data_node(id=f"ds_{i}", storage_type="in_memory", scope=Scope.SCENARIO))
  132. return configs
  133. def __default_task():
  134. input_ds = PickleDataNode(
  135. "input_ds",
  136. Scope.SCENARIO,
  137. DataNodeId("id_uio"),
  138. "owner_id",
  139. {"TASK_task_id"},
  140. properties={"default_data": "In memory Data Source"},
  141. )
  142. output_ds = PickleDataNode(
  143. "output_ds",
  144. Scope.SCENARIO,
  145. DataNodeId("id_uio"),
  146. "owner_id",
  147. {"TASK_task_id"},
  148. properties={"default_data": "In memory Data Source"},
  149. )
  150. return Task(
  151. config_id="foo",
  152. properties={},
  153. function=print,
  154. input=[input_ds],
  155. output=[output_ds],
  156. id="TASK_task_id",
  157. )
  158. @pytest.fixture
  159. def default_task():
  160. return __default_task()
  161. @pytest.fixture
  162. def default_task_config():
  163. return Config.configure_task("task1", print, [], [])
  164. @pytest.fixture
  165. def default_task_config_list():
  166. configs = []
  167. for i in range(10):
  168. configs.append(Config.configure_task(f"task_{i}", print, [], []))
  169. return configs
  170. def __default_sequence():
  171. return Sequence(properties={"name": "foo"}, tasks=[__default_task()], sequence_id="SEQUENCE_foo_SCENARIO_acb")
  172. def __task_config():
  173. return Config.configure_task("task1", print, [], [])
  174. @pytest.fixture
  175. def default_sequence():
  176. return __default_sequence()
  177. @pytest.fixture
  178. def default_scenario_config():
  179. task_config = __task_config()
  180. scenario_config = Config.configure_scenario(
  181. f"taipy_{uuid.uuid4().hex}",
  182. [task_config],
  183. )
  184. scenario_config.add_sequences({"sequence": [task_config]})
  185. return scenario_config
  186. @pytest.fixture
  187. def default_scenario_config_list():
  188. configs = []
  189. for _ in range(10):
  190. task_config = Config.configure_task(f"taipy_{uuid.uuid4().hex}", print)
  191. scenario_config = Config.configure_scenario(
  192. f"taipy_{uuid.uuid4().hex}",
  193. [task_config],
  194. )
  195. scenario_config.add_sequences({"sequence": [task_config]})
  196. configs.append(scenario_config)
  197. return configs
  198. @pytest.fixture
  199. def default_scenario():
  200. return Scenario(config_id="foo", properties={}, tasks=[__default_task()], scenario_id="SCENARIO_scenario_id")
  201. def __create_cycle(name="foo"):
  202. now = datetime.now()
  203. return Cycle(
  204. name=name,
  205. frequency=Frequency.DAILY,
  206. properties={},
  207. creation_date=now,
  208. start_date=now,
  209. end_date=now + timedelta(days=5),
  210. )
  211. @pytest.fixture
  212. def create_cycle_list():
  213. cycles = []
  214. manager = _CycleManager
  215. for i in range(10):
  216. c = __create_cycle(f"cycle_{i}")
  217. manager._set(c)
  218. return cycles
  219. @pytest.fixture
  220. def cycle_data():
  221. return {
  222. "name": "foo",
  223. "frequency": "daily",
  224. "properties": {},
  225. "creation_date": "2022-02-03T22:17:27.317114",
  226. "start_date": "2022-02-03T22:17:27.317114",
  227. "end_date": "2022-02-08T22:17:27.317114",
  228. }
  229. @pytest.fixture
  230. def default_cycle():
  231. return __create_cycle()
  232. def __create_job():
  233. task_manager = _TaskManager
  234. task = __default_task()
  235. task_manager._set(task)
  236. submit_id = f"SUBMISSION_{str(uuid.uuid4())}"
  237. return Job(id=JobId(f"JOB_{uuid.uuid4()}"), task=task, submit_id=submit_id, submit_entity_id=task.id)
  238. @pytest.fixture
  239. def default_job():
  240. return __create_job()
  241. @pytest.fixture
  242. def create_job_list():
  243. jobs = []
  244. manager = _JobManager
  245. for _ in range(10):
  246. c = __create_job()
  247. manager._set(c)
  248. return jobs
  249. @pytest.fixture
  250. def init_orchestrator():
  251. def _init_orchestrator():
  252. _OrchestratorFactory._remove_dispatcher()
  253. if _OrchestratorFactory._orchestrator is None:
  254. _OrchestratorFactory._build_orchestrator()
  255. _OrchestratorFactory._build_dispatcher(force_restart=True)
  256. _OrchestratorFactory._orchestrator.jobs_to_run = Queue()
  257. _OrchestratorFactory._orchestrator.blocked_jobs = []
  258. return _init_orchestrator
  259. @pytest.fixture(scope="function", autouse=True)
  260. def cleanup_files(reset_configuration_singleton, inject_rest_sections, inject_core_sections):
  261. reset_configuration_singleton()
  262. inject_core_sections()
  263. inject_rest_sections()
  264. _Checker.add_checker(_RestConfigChecker)
  265. Config.configure_core(repository_type="filesystem")
  266. if os.path.exists(".data"):
  267. shutil.rmtree(".data", ignore_errors=True)
  268. if os.path.exists(".my_data"):
  269. shutil.rmtree(".my_data", ignore_errors=True)
  270. yield
  271. for path in [".data", ".my_data", "user_data", ".taipy"]:
  272. if os.path.exists(path):
  273. shutil.rmtree(path, ignore_errors=True)