test_override_config.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. import pytest
  14. from taipy.common.config import Config
  15. from taipy.common.config.exceptions.exceptions import InconsistentEnvVariableError, MissingEnvVariableError
  16. from tests.core.utils.named_temporary_file import NamedTemporaryFile
  17. def test_override_default_configuration_with_code_configuration():
  18. assert not Config.core.root_folder == "foo"
  19. assert len(Config.data_nodes) == 1
  20. assert len(Config.tasks) == 1
  21. assert len(Config.scenarios) == 1
  22. Config.configure_job_executions(max_nb_of_workers=-1)
  23. Config.configure_core(root_folder="foo")
  24. foo_config = Config.configure_data_node("foo", "in_memory")
  25. xyz_config = Config.configure_data_node("xyz")
  26. bar_config = Config.configure_task("bar", print, [foo_config], [])
  27. qux_config = Config.configure_scenario("qux", [bar_config], [xyz_config])
  28. assert Config.job_config.max_nb_of_workers == -1
  29. assert Config.core.root_folder == "foo"
  30. assert len(Config.data_nodes) == 3
  31. assert "default" in Config.data_nodes
  32. assert foo_config.id in Config.data_nodes
  33. assert xyz_config.id in Config.data_nodes
  34. assert Config.data_nodes[foo_config.id].storage_type == "in_memory"
  35. assert Config.data_nodes[xyz_config.id].storage_type == "pickle"
  36. assert len(Config.tasks) == 2
  37. assert "default" in Config.tasks
  38. assert bar_config.id in Config.tasks
  39. assert len(Config.tasks[bar_config.id].input_configs) == 1
  40. assert Config.tasks[bar_config.id].input_configs[0].id == foo_config.id
  41. assert len(Config.tasks[bar_config.id].output_configs) == 0
  42. assert Config.tasks[bar_config.id].function == print
  43. assert len(Config.scenarios) == 2
  44. assert "default" in Config.scenarios
  45. assert qux_config.id in Config.scenarios
  46. assert len(Config.scenarios[qux_config.id].tasks) == 1
  47. assert Config.scenarios[qux_config.id].tasks[0].id == bar_config.id
  48. assert len(Config.scenarios[qux_config.id].additional_data_nodes) == 1
  49. assert Config.scenarios[qux_config.id].additional_data_nodes[0].id == xyz_config.id
  50. def test_override_default_config_with_code_config_including_env_variable_values():
  51. Config.configure_core()
  52. assert Config.core.repository_type == "filesystem"
  53. with mock.patch.dict(os.environ, {"REPOSITORY_TYPE": "foo"}):
  54. Config.configure_core(repository_type="ENV[REPOSITORY_TYPE]")
  55. assert Config.core.repository_type == "foo"
  56. Config.configure_core(repository_type="othertype")
  57. assert Config.core.repository_type == "othertype"
  58. def test_override_default_configuration_with_file_configuration():
  59. tf = NamedTemporaryFile(
  60. """
  61. [TAIPY]
  62. [JOB]
  63. max_nb_of_workers = -1
  64. [DATA_NODE.foo]
  65. [TASK.bar]
  66. [SCENARIO.qux]
  67. """
  68. )
  69. assert Config.job_config.mode == "development"
  70. assert Config.job_config.max_nb_of_workers is None
  71. assert len(Config.data_nodes) == 1
  72. assert len(Config.tasks) == 1
  73. assert len(Config.scenarios) == 1
  74. Config.override(tf.filename)
  75. assert Config.job_config.max_nb_of_workers == -1
  76. assert len(Config.data_nodes) == 2
  77. assert "default" in Config.data_nodes
  78. assert "foo" in Config.data_nodes
  79. assert len(Config.tasks) == 2
  80. assert "default" in Config.tasks
  81. assert "bar" in Config.tasks
  82. assert "default" in Config.scenarios
  83. assert len(Config.scenarios) == 2
  84. assert "qux" in Config.scenarios
  85. def test_override_default_config_with_file_config_including_env_variable_values():
  86. tf = NamedTemporaryFile(
  87. """
  88. [JOB]
  89. max_nb_of_workers = "ENV[FOO]:int"
  90. start_executor = "ENV[BAR]"
  91. """
  92. )
  93. assert Config.job_config.mode == "development"
  94. assert Config.job_config.max_nb_of_workers is None
  95. assert not Config.job_config.start_executor
  96. with mock.patch.dict(os.environ, {"FOO": "6", "BAR": "TRUe"}):
  97. Config.override(tf.filename)
  98. assert Config.job_config.max_nb_of_workers == 6
  99. assert Config.job_config.start_executor
  100. with mock.patch.dict(os.environ, {"FOO": "foo", "BAR": "true"}):
  101. Config.override(tf.filename)
  102. with pytest.raises(InconsistentEnvVariableError):
  103. _ = Config.job_config.max_nb_of_workers
  104. with mock.patch.dict(os.environ, {"FOO": "5"}):
  105. Config.override(tf.filename)
  106. assert Config.job_config.max_nb_of_workers == 5
  107. with pytest.raises(MissingEnvVariableError):
  108. _ = Config.job_config.start_executor
  109. def test_code_configuration_do_not_override_file_configuration():
  110. config_from_filename = NamedTemporaryFile(
  111. """
  112. [JOB]
  113. max_nb_of_workers = 2
  114. """
  115. )
  116. Config.override(config_from_filename.filename)
  117. Config.configure_job_executions(max_nb_of_workers=21)
  118. assert Config.job_config.max_nb_of_workers == 2 # From file config
  119. def test_code_configuration_do_not_override_file_configuration_including_env_variable_values():
  120. config_from_filename = NamedTemporaryFile(
  121. """
  122. [JOB]
  123. max_nb_of_workers = 2
  124. """
  125. )
  126. Config.override(config_from_filename.filename)
  127. with mock.patch.dict(os.environ, {"FOO": "21"}):
  128. Config.configure_job_executions(max_nb_of_workers="ENV[FOO]")
  129. assert Config.job_config.max_nb_of_workers == 2 # From file config
  130. def test_file_configuration_override_code_configuration():
  131. config_from_filename = NamedTemporaryFile(
  132. """
  133. [JOB]
  134. max_nb_of_workers = 2
  135. """
  136. )
  137. Config.configure_job_executions(max_nb_of_workers=21)
  138. Config.override(config_from_filename.filename)
  139. assert Config.job_config.max_nb_of_workers == 2 # From file config
  140. def test_file_configuration_override_code_configuration_including_env_variable_values():
  141. config_from_filename = NamedTemporaryFile(
  142. """
  143. [JOB]
  144. max_nb_of_workers = "ENV[FOO]:int"
  145. """
  146. )
  147. Config.configure_job_executions(max_nb_of_workers=21)
  148. with mock.patch.dict(os.environ, {"FOO": "2"}):
  149. Config.override(config_from_filename.filename)
  150. assert Config.job_config.max_nb_of_workers == 2 # From file config
  151. def test_override_default_configuration_with_multiple_configurations():
  152. file_config = NamedTemporaryFile(
  153. """
  154. [DATA_NODE.default]
  155. has_header = true
  156. [DATA_NODE.my_datanode]
  157. path = "/data/csv"
  158. [JOB]
  159. max_nb_of_workers = 10
  160. [TAIPY]
  161. """
  162. )
  163. # Default config is applied
  164. assert Config.job_config.mode == "development"
  165. assert Config.job_config.max_nb_of_workers is None
  166. # Code config is applied
  167. Config.configure_job_executions(max_nb_of_workers=-1)
  168. assert Config.job_config.max_nb_of_workers == -1
  169. # File config is applied
  170. Config.override(file_config.filename)
  171. assert Config.job_config.max_nb_of_workers == 10
  172. assert Config.data_nodes["my_datanode"].has_header
  173. assert Config.data_nodes["my_datanode"].path == "/data/csv"
  174. assert Config.data_nodes["my_datanode"].not_defined is None
  175. def test_override_default_configuration_with_multiple_configurations_including_environment_variable_values():
  176. file_config = NamedTemporaryFile(
  177. """
  178. [DATA_NODE.default]
  179. has_header = true
  180. [DATA_NODE.my_datanode]
  181. path = "ENV[FOO]"
  182. [JOB]
  183. max_nb_of_workers = 10
  184. [TAIPY]
  185. """
  186. )
  187. with mock.patch.dict(os.environ, {"FOO": "/data/csv", "BAR": "/baz/data/csv"}):
  188. # Default config is applied
  189. assert Config.job_config.mode == "development"
  190. assert Config.job_config.max_nb_of_workers is None
  191. # Code config is applied
  192. Config.configure_job_executions(max_nb_of_workers=-1)
  193. Config.configure_data_node("my_datanode", path="ENV[BAR]")
  194. assert Config.job_config.max_nb_of_workers == -1
  195. assert Config.data_nodes["my_datanode"].path == "/baz/data/csv"
  196. # File config is applied
  197. Config.override(file_config.filename)
  198. assert Config.job_config.max_nb_of_workers == 10
  199. assert Config.data_nodes["my_datanode"].has_header
  200. assert Config.data_nodes["my_datanode"].path == "/data/csv"
  201. assert Config.data_nodes["my_datanode"].not_defined is None