test_task_config.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. from unittest import mock
  13. from taipy import Scope
  14. from taipy.common.config import Config
  15. from taipy.core.config import DataNodeConfig
  16. from tests.core.utils.named_temporary_file import NamedTemporaryFile
  17. def _configure_task_in_toml():
  18. return NamedTemporaryFile(
  19. content="""
  20. [TAIPY]
  21. [DATA_NODE.input]
  22. [DATA_NODE.output]
  23. [TASK.tasks1]
  24. function = "builtins.print:function"
  25. inputs = [ "input:SECTION",]
  26. outputs = [ "output:SECTION",]
  27. """
  28. )
  29. def _check_data_nodes_instance(dn_id, task_id):
  30. """Check if the data node instance in the task config correctly points to the Config._applied_config,
  31. not the Config._python_config or the Config._file_config
  32. """
  33. dn_config_applied_instance = Config.data_nodes[dn_id]
  34. for dn in Config.tasks[task_id].inputs:
  35. if dn.id == dn_id:
  36. dn_config_instance_via_task = dn
  37. for dn in Config.tasks[task_id].outputs:
  38. if dn.id == dn_id:
  39. dn_config_instance_via_task = dn
  40. dn_config_python_instance = None
  41. if Config._python_config._sections.get("DATA_NODE", None):
  42. dn_config_python_instance = Config._python_config._sections["DATA_NODE"][dn_id]
  43. dn_config_file_instance = None
  44. if Config._file_config._sections.get("DATA_NODE", None):
  45. dn_config_file_instance = Config._file_config._sections["DATA_NODE"][dn_id]
  46. if dn_config_python_instance:
  47. assert dn_config_python_instance.scope is None
  48. assert dn_config_python_instance is not dn_config_applied_instance
  49. assert dn_config_python_instance is not dn_config_instance_via_task
  50. if dn_config_file_instance:
  51. assert dn_config_file_instance.scope is None
  52. assert dn_config_file_instance is not dn_config_applied_instance
  53. assert dn_config_file_instance is not dn_config_instance_via_task
  54. assert dn_config_applied_instance.scope == DataNodeConfig._DEFAULT_SCOPE
  55. assert dn_config_instance_via_task is dn_config_applied_instance
  56. def test_data_node_instance_when_configure_task_in_python():
  57. input_config = Config.configure_data_node("input")
  58. output_config = Config.configure_data_node("output")
  59. Config.configure_task("tasks1", print, input_config, output_config)
  60. _check_data_nodes_instance("input", "tasks1")
  61. _check_data_nodes_instance("output", "tasks1")
  62. def test_data_node_instance_when_configure_task_by_loading_toml():
  63. toml_config = _configure_task_in_toml()
  64. Config.load(toml_config.filename)
  65. _check_data_nodes_instance("input", "tasks1")
  66. _check_data_nodes_instance("output", "tasks1")
  67. def test_data_node_instance_when_configure_task_by_overriding_toml():
  68. toml_config = _configure_task_in_toml()
  69. Config.override(toml_config.filename)
  70. _check_data_nodes_instance("input", "tasks1")
  71. _check_data_nodes_instance("output", "tasks1")
  72. def test_task_config_creation():
  73. input_config = Config.configure_data_node("input")
  74. output_config = Config.configure_data_node("output", scope=Scope.GLOBAL)
  75. other_config = Config.configure_data_node("other", scope=Scope.CYCLE)
  76. task_config = Config.configure_task("task1", print, input_config, output_config)
  77. assert list(Config.tasks) == ["default", task_config.id]
  78. assert not task_config.skippable
  79. assert task_config.id == "task1"
  80. assert task_config.function == print
  81. assert task_config.input_configs == [input_config]
  82. assert task_config.output_configs == [output_config]
  83. assert task_config.scope == Scope.SCENARIO
  84. assert task_config.properties == {}
  85. task_config_2 = Config.configure_task("task2", print, other_config, output_config, skippable=True)
  86. assert list(Config.tasks) == ["default", task_config.id, task_config_2.id]
  87. assert task_config_2.skippable
  88. assert task_config_2.id == "task2"
  89. assert task_config_2.function == print
  90. assert task_config_2.input_configs == [other_config]
  91. assert task_config_2.output_configs == [output_config]
  92. assert task_config_2.scope == Scope.CYCLE
  93. assert task_config_2.properties == {}
  94. def test_task_count():
  95. input_config = Config.configure_data_node("input")
  96. output_config = Config.configure_data_node("output")
  97. Config.configure_task("tasks1", print, input_config, output_config)
  98. assert len(Config.tasks) == 2
  99. Config.configure_task("tasks2", print, input_config, output_config)
  100. assert len(Config.tasks) == 3
  101. Config.configure_task("tasks3", print, input_config, output_config)
  102. assert len(Config.tasks) == 4
  103. def test_task_getitem():
  104. input_config = Config.configure_data_node("input")
  105. output_config = Config.configure_data_node("output")
  106. task_id = "tasks1"
  107. task_cfg = Config.configure_task(task_id, print, input_config, output_config)
  108. assert Config.tasks[task_id].id == task_cfg.id
  109. assert Config.tasks[task_id].properties == task_cfg.properties
  110. assert Config.tasks[task_id].function == task_cfg.function
  111. assert Config.tasks[task_id].input_configs == task_cfg.input_configs
  112. assert Config.tasks[task_id].output_configs == task_cfg.output_configs
  113. assert Config.tasks[task_id].skippable == task_cfg.skippable
  114. def test_task_creation_no_duplication():
  115. input_config = Config.configure_data_node("input")
  116. output_config = Config.configure_data_node("output")
  117. Config.configure_task("tasks1", print, input_config, output_config)
  118. assert len(Config.tasks) == 2
  119. Config.configure_task("tasks1", print, input_config, output_config)
  120. assert len(Config.tasks) == 2
  121. def test_task_config_with_env_variable_value():
  122. input_config = Config.configure_data_node("input")
  123. output_config = Config.configure_data_node("output")
  124. with mock.patch.dict(os.environ, {"FOO": "plop", "BAR": "baz"}):
  125. Config.configure_task("task_name", print, input_config, output_config, prop="ENV[BAR]")
  126. assert Config.tasks["task_name"].prop == "baz"
  127. assert Config.tasks["task_name"].properties["prop"] == "baz"
  128. assert Config.tasks["task_name"]._properties["prop"] == "ENV[BAR]"
  129. def test_clean_config():
  130. dn1 = Config.configure_data_node("dn1")
  131. dn2 = Config.configure_data_node("dn2")
  132. task1_config = Config.configure_task("id1", print, dn1, dn2)
  133. task2_config = Config.configure_task("id2", print, dn2, dn1)
  134. assert Config.tasks["id1"] is task1_config
  135. assert Config.tasks["id2"] is task2_config
  136. task1_config._clean()
  137. task2_config._clean()
  138. # Check if the instance before and after _clean() is the same
  139. assert Config.tasks["id1"] is task1_config
  140. assert Config.tasks["id2"] is task2_config
  141. assert task1_config.id == "id1"
  142. assert task2_config.id == "id2"
  143. assert task1_config.function is task1_config.function is None
  144. assert task1_config.inputs == task1_config.inputs == []
  145. assert task1_config.input_configs == task1_config.input_configs == []
  146. assert task1_config.outputs == task1_config.outputs == []
  147. assert task1_config.output_configs == task1_config.output_configs == []
  148. assert task1_config.skippable is task1_config.skippable is False
  149. assert task1_config.properties == task1_config.properties == {}