test_generic_data_node.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. import pytest
  12. from taipy.config.common.scope import Scope
  13. from taipy.config.exceptions.exceptions import InvalidConfigurationId
  14. from taipy.core.data.data_node import DataNode
  15. from taipy.core.data.data_node_id import DataNodeId
  16. from taipy.core.data.generic import GenericDataNode
  17. from taipy.core.exceptions.exceptions import MissingReadFunction, MissingRequiredProperty, MissingWriteFunction
  18. def read_fct():
  19. return TestGenericDataNode.data
  20. def read_fct_with_args(inp):
  21. return [i + inp for i in TestGenericDataNode.data]
  22. def write_fct(data):
  23. data.append(data[-1] + 1)
  24. def write_fct_with_args(data, inp):
  25. for _ in range(inp):
  26. data.append(data[-1] + 1)
  27. def read_fct_modify_data_node_name(data_node_id: DataNodeId, name: str):
  28. import taipy.core as tp
  29. data_node = tp.get(data_node_id)
  30. assert isinstance(data_node, DataNode)
  31. data_node.name = name # type:ignore
  32. return data_node
  33. def reset_data():
  34. TestGenericDataNode.data = list(range(10))
  35. class TestGenericDataNode:
  36. data = list(range(10))
  37. def test_create(self):
  38. dn = GenericDataNode(
  39. "foo_bar", Scope.SCENARIO, properties={"read_fct": read_fct, "write_fct": write_fct, "name": "super name"}
  40. )
  41. assert isinstance(dn, GenericDataNode)
  42. assert dn.storage_type() == "generic"
  43. assert dn.config_id == "foo_bar"
  44. assert dn.name == "super name"
  45. assert dn.scope == Scope.SCENARIO
  46. assert dn.id is not None
  47. assert dn.owner_id is None
  48. assert dn.last_edit_date is not None
  49. assert dn.job_ids == []
  50. assert dn.is_ready_for_reading
  51. assert dn.properties["read_fct"] == read_fct
  52. assert dn.properties["write_fct"] == write_fct
  53. dn_1 = GenericDataNode(
  54. "foo", Scope.SCENARIO, properties={"read_fct": read_fct, "write_fct": None, "name": "foo"}
  55. )
  56. assert isinstance(dn, GenericDataNode)
  57. assert dn_1.storage_type() == "generic"
  58. assert dn_1.config_id == "foo"
  59. assert dn_1.name == "foo"
  60. assert dn_1.scope == Scope.SCENARIO
  61. assert dn_1.id is not None
  62. assert dn_1.owner_id is None
  63. assert dn_1.last_edit_date is not None
  64. assert dn_1.job_ids == []
  65. assert dn_1.is_ready_for_reading
  66. assert dn_1.properties["read_fct"] == read_fct
  67. assert dn_1.properties["write_fct"] is None
  68. dn_2 = GenericDataNode(
  69. "xyz", Scope.SCENARIO, properties={"read_fct": None, "write_fct": write_fct, "name": "xyz"}
  70. )
  71. assert isinstance(dn, GenericDataNode)
  72. assert dn_2.storage_type() == "generic"
  73. assert dn_2.config_id == "xyz"
  74. assert dn_2.name == "xyz"
  75. assert dn_2.scope == Scope.SCENARIO
  76. assert dn_2.id is not None
  77. assert dn_2.owner_id is None
  78. assert dn_2.last_edit_date is not None
  79. assert dn_2.job_ids == []
  80. assert dn_2.is_ready_for_reading
  81. assert dn_2.properties["read_fct"] is None
  82. assert dn_2.properties["write_fct"] == write_fct
  83. dn_3 = GenericDataNode("xyz", Scope.SCENARIO, properties={"read_fct": read_fct, "name": "xyz"})
  84. assert isinstance(dn, GenericDataNode)
  85. assert dn_3.storage_type() == "generic"
  86. assert dn_3.config_id == "xyz"
  87. assert dn_3.name == "xyz"
  88. assert dn_3.scope == Scope.SCENARIO
  89. assert dn_3.id is not None
  90. assert dn_3.owner_id is None
  91. assert dn_3.last_edit_date is not None
  92. assert dn_3.job_ids == []
  93. assert dn_3.is_ready_for_reading
  94. assert dn_3.properties["read_fct"] == read_fct
  95. assert dn_3.properties["write_fct"] is None
  96. dn_4 = GenericDataNode("xyz", Scope.SCENARIO, properties={"write_fct": write_fct, "name": "xyz"})
  97. assert isinstance(dn, GenericDataNode)
  98. assert dn_4.storage_type() == "generic"
  99. assert dn_4.config_id == "xyz"
  100. assert dn_4.name == "xyz"
  101. assert dn_4.scope == Scope.SCENARIO
  102. assert dn_4.id is not None
  103. assert dn_4.owner_id is None
  104. assert dn_4.last_edit_date is not None
  105. assert dn_4.job_ids == []
  106. assert dn_4.is_ready_for_reading
  107. assert dn_4.properties["read_fct"] is None
  108. assert dn_4.properties["write_fct"] == write_fct
  109. with pytest.raises(InvalidConfigurationId):
  110. GenericDataNode("foo bar", Scope.SCENARIO, properties={"read_fct": read_fct, "write_fct": write_fct})
  111. def test_get_user_properties(self):
  112. dn_1 = GenericDataNode(
  113. "dn_1",
  114. Scope.SCENARIO,
  115. properties={
  116. "read_fct": read_fct,
  117. "write_fct": write_fct,
  118. "read_fct_args": 1,
  119. "write_fct_args": 2,
  120. "foo": "bar",
  121. },
  122. )
  123. # read_fct, read_fct_args, write_fct, write_fct_args are filtered out
  124. assert dn_1._get_user_properties() == {"foo": "bar"}
  125. def test_create_with_missing_parameters(self):
  126. with pytest.raises(MissingRequiredProperty):
  127. GenericDataNode("foo", Scope.SCENARIO, DataNodeId("dn_id"))
  128. with pytest.raises(MissingRequiredProperty):
  129. GenericDataNode("foo", Scope.SCENARIO, DataNodeId("dn_id"), properties={})
  130. def test_read_write_generic_datanode(self):
  131. generic_dn = GenericDataNode("foo", Scope.SCENARIO, properties={"read_fct": read_fct, "write_fct": write_fct})
  132. assert generic_dn.read() == self.data
  133. assert len(generic_dn.read()) == 10
  134. generic_dn.write(self.data)
  135. assert generic_dn.read() == self.data
  136. assert len(generic_dn.read()) == 11
  137. generic_dn_1 = GenericDataNode("bar", Scope.SCENARIO, properties={"read_fct": read_fct, "write_fct": None})
  138. assert generic_dn_1.read() == self.data
  139. assert len(generic_dn_1.read()) == 11
  140. with pytest.raises(MissingWriteFunction):
  141. generic_dn_1.write(self.data)
  142. generic_dn_2 = GenericDataNode("xyz", Scope.SCENARIO, properties={"read_fct": None, "write_fct": write_fct})
  143. generic_dn_2.write(self.data)
  144. assert len(self.data) == 12
  145. with pytest.raises(MissingReadFunction):
  146. generic_dn_2.read()
  147. generic_dn_3 = GenericDataNode("bar", Scope.SCENARIO, properties={"read_fct": None, "write_fct": None})
  148. with pytest.raises(MissingReadFunction):
  149. generic_dn_3.read()
  150. with pytest.raises(MissingWriteFunction):
  151. generic_dn_3.write(self.data)
  152. reset_data()
  153. def test_read_write_generic_datanode_with_arguments(self):
  154. generic_dn = GenericDataNode(
  155. "foo",
  156. Scope.SCENARIO,
  157. properties={
  158. "read_fct": read_fct_with_args,
  159. "write_fct": write_fct_with_args,
  160. "read_fct_args": [1],
  161. "write_fct_args": [2],
  162. },
  163. )
  164. assert all(a + 1 == b for a, b in zip(self.data, generic_dn.read()))
  165. assert len(generic_dn.read()) == 10
  166. generic_dn.write(self.data)
  167. assert len(generic_dn.read()) == 12
  168. reset_data()
  169. def test_read_write_generic_datanode_with_non_list_arguments(self):
  170. generic_dn = GenericDataNode(
  171. "foo",
  172. Scope.SCENARIO,
  173. properties={
  174. "read_fct": read_fct_with_args,
  175. "write_fct": write_fct_with_args,
  176. "read_fct_args": 1,
  177. "write_fct_args": 2,
  178. },
  179. )
  180. assert all(a + 1 == b for a, b in zip(self.data, generic_dn.read()))
  181. assert len(generic_dn.read()) == 10
  182. generic_dn.write(self.data)
  183. assert len(generic_dn.read()) == 12
  184. reset_data()
  185. def test_save_data_node_when_read(self):
  186. generic_dn = GenericDataNode(
  187. "foo", Scope.SCENARIO, properties={"read_fct": read_fct_modify_data_node_name, "write_fct": write_fct}
  188. )
  189. generic_dn._properties["read_fct_args"] = (generic_dn.id, "bar")
  190. generic_dn.read()
  191. assert generic_dn.name == "bar"