test_entity_address_utils.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import pytest
  2. from flexmeasures.utils.entity_address_utils import (
  3. build_entity_address,
  4. parse_entity_address,
  5. EntityAddressException,
  6. build_ea_scheme_and_naming_authority,
  7. reverse_domain_name,
  8. )
  9. from flexmeasures.utils.time_utils import get_first_day_of_next_month
  10. @pytest.mark.parametrize(
  11. "info, entity_type, host, fm_scheme, exp_result",
  12. [
  13. (
  14. dict(sensor_id=42),
  15. "sensor",
  16. "flexmeasures.io",
  17. "fm1",
  18. "ea1.2021-01.io.flexmeasures:fm1.42",
  19. ),
  20. (
  21. dict(asset_id=42),
  22. "sensor",
  23. "flexmeasures.io",
  24. "fm1",
  25. "required field 'sensor_id'",
  26. ),
  27. (
  28. dict(sensor_id=40),
  29. "connection",
  30. "flexmeasures.io",
  31. "fm1",
  32. "ea1.2021-01.io.flexmeasures:fm1.40",
  33. ),
  34. (
  35. dict(asset_id=40),
  36. "connection",
  37. "flexmeasures.io",
  38. "fm1",
  39. "required field 'sensor_id'",
  40. ),
  41. (
  42. dict(owner_id=3, asset_id=40),
  43. "connection",
  44. "flexmeasures.io",
  45. "fm0",
  46. "ea1.2021-01.io.flexmeasures:fm0.3:40",
  47. ),
  48. (
  49. dict(owner_id=3),
  50. "connection",
  51. "flexmeasures.io",
  52. "fm0",
  53. "required field 'asset_id'",
  54. ),
  55. (
  56. dict(owner_id=40, asset_id=30),
  57. "connection",
  58. "localhost:5000",
  59. "fm0",
  60. f"ea1.{get_first_day_of_next_month().strftime('%Y-%m')}.localhost:fm0.40:30",
  61. ),
  62. (
  63. dict(
  64. weather_sensor_type_name="temperature",
  65. latitude=52,
  66. longitude=73.0,
  67. ),
  68. "weather_sensor",
  69. "flexmeasures.io",
  70. "fm0",
  71. "ea1.2021-01.io.flexmeasures:fm0.temperature:52:73.0",
  72. ),
  73. (
  74. dict(market_name="epex_da"),
  75. "market",
  76. "flexmeasures.io",
  77. "fm0",
  78. "ea1.2021-01.io.flexmeasures:fm0.epex_da",
  79. ),
  80. (
  81. dict(
  82. owner_id=40,
  83. asset_id=30,
  84. event_type="soc",
  85. event_id=302,
  86. ),
  87. "event",
  88. "http://staging.flexmeasures.io:4444",
  89. "fm0",
  90. "ea1.2022-09.io.flexmeasures.staging:fm0.40:30:302:soc",
  91. ),
  92. ],
  93. )
  94. def test_build_entity_address(
  95. app, info: dict, entity_type: str, host: str, fm_scheme: str, exp_result: str
  96. ):
  97. app.config["FLEXMEASURES_HOSTS_AND_AUTH_START"] = {
  98. "flexmeasures.io": "2021-01",
  99. "staging.flexmeasures.io": "2022-09",
  100. }
  101. if exp_result.startswith("ea1"):
  102. assert build_entity_address(info, entity_type, host, fm_scheme) == exp_result
  103. else:
  104. with pytest.raises(EntityAddressException, match=exp_result):
  105. build_entity_address(info, entity_type, host, fm_scheme) == exp_result
  106. @pytest.mark.parametrize(
  107. "entity_type, entity_address, exp_result",
  108. [
  109. (
  110. "connection",
  111. "ea2.2018-06.localhost:40:30",
  112. "starts with 'ea1'",
  113. ),
  114. (
  115. "connection",
  116. "ea1.2018-RR.localhost:40:30",
  117. "date specification",
  118. ),
  119. (
  120. "weather_sensor",
  121. "ea1.2018-04.localhost:5000:40:30",
  122. "Could not parse", # no sensor type (which starts with a letter)
  123. ),
  124. ("connection", "ea1:40", "a date spec"), # trying only an asset ID
  125. (
  126. "connection",
  127. "ea1.2018-06.localhost:5000:40:30",
  128. dict(naming_authority="2018-06.localhost", owner_id=40, asset_id=30),
  129. ),
  130. (
  131. "connection",
  132. "ea1.2018-06.localhost:40",
  133. dict(naming_authority="2018-06.localhost", asset_id=40, owner_id=None),
  134. ),
  135. (
  136. "connection",
  137. "ea1.2018-06.io.flexmeasures:40:30",
  138. dict(naming_authority="2018-06.io.flexmeasures", owner_id=40, asset_id=30),
  139. ),
  140. (
  141. "weather_sensor",
  142. "ea1.2018-06.io.flexmeasures:temperature:-52:73.0",
  143. dict(
  144. naming_authority="2018-06.io.flexmeasures",
  145. weather_sensor_type_name="temperature",
  146. latitude=-52,
  147. longitude=73.0,
  148. ),
  149. ),
  150. (
  151. "market",
  152. "ea1.2018-06.io.flexmeasures:epex_da",
  153. dict(naming_authority="2018-06.io.flexmeasures", market_name="epex_da"),
  154. ),
  155. (
  156. "event",
  157. "ea1.2018-06.io.flexmeasures.staging:40:30:302:soc",
  158. dict(
  159. naming_authority="2018-06.io.flexmeasures.staging",
  160. owner_id=40,
  161. asset_id=30,
  162. event_type="soc",
  163. event_id=302,
  164. ),
  165. ),
  166. (
  167. "event",
  168. "ea1.2018-06.io.flexmeasures.staging:30:302:soc",
  169. dict(
  170. naming_authority="2018-06.io.flexmeasures.staging",
  171. asset_id=30,
  172. owner_id=None,
  173. event_type="soc",
  174. event_id=302,
  175. ),
  176. ),
  177. (
  178. "connection",
  179. "ea1.2018-06.io.flexmeasures.staging:fm1.30",
  180. dict(
  181. naming_authority="2018-06.io.flexmeasures.staging",
  182. asset_id=30,
  183. owner_id=None,
  184. event_type="connection",
  185. ),
  186. ),
  187. ],
  188. )
  189. def test_parse_entity_address(entity_type, entity_address, exp_result):
  190. if isinstance(exp_result, str): # this means we expect an exception
  191. with pytest.raises(EntityAddressException, match=exp_result):
  192. parse_entity_address(
  193. entity_address, entity_type=entity_type, fm_scheme="fm0"
  194. )
  195. else:
  196. res = parse_entity_address(
  197. entity_address, entity_type=entity_type, fm_scheme="fm0"
  198. )
  199. assert res["scheme"] == "ea1"
  200. assert res["naming_authority"] == exp_result["naming_authority"]
  201. if entity_type in ("connection", "event"):
  202. for field in ("asset_id", "owner_id"):
  203. assert res[field] == exp_result[field]
  204. if entity_type == "market":
  205. assert res["market_name"] == exp_result["market_name"]
  206. if entity_type == "weather_sensor":
  207. for field in ("weather_sensor_type_name", "latitude", "longitude"):
  208. assert res[field] == exp_result[field]
  209. if entity_type == "event":
  210. for field in ("event_type", "event_id"):
  211. assert res[field] == exp_result[field]
  212. def test_reverse_domain_name():
  213. assert reverse_domain_name("flexmeasures.io") == "io.flexmeasures"
  214. assert reverse_domain_name("company.flexmeasures.io") == "io.flexmeasures.company"
  215. assert (
  216. reverse_domain_name("staging.company.flexmeasures.org")
  217. == "org.flexmeasures.company.staging"
  218. )
  219. assert (
  220. reverse_domain_name("staging.company.flexmeasures.io:4500")
  221. == "io.flexmeasures.company.staging"
  222. )
  223. assert (
  224. reverse_domain_name("https://staging.company.flexmeasures.io:4500")
  225. == "io.flexmeasures.company.staging"
  226. )
  227. assert (
  228. reverse_domain_name("https://user:pass@staging.company.flexmeasures.io:4500")
  229. == "io.flexmeasures.company.staging"
  230. )
  231. assert reverse_domain_name("test.flexmeasures.co.uk") == "uk.co.flexmeasures.test"
  232. assert (
  233. reverse_domain_name("test.staging.flexmeasures.co.uk")
  234. == "uk.co.flexmeasures.staging.test"
  235. )
  236. def test_build_ea_scheme_and_naming_authority(app):
  237. assert build_ea_scheme_and_naming_authority(
  238. "localhost:5000"
  239. ) == "ea1.%s.localhost" % get_first_day_of_next_month().strftime("%Y-%m")
  240. assert (
  241. build_ea_scheme_and_naming_authority("flexmeasures.io")
  242. == "ea1.2021-01.io.flexmeasures"
  243. )
  244. app.config["FLEXMEASURES_HOSTS_AND_AUTH_START"] = {
  245. "flexmeasures.io": "2021-01",
  246. "company.flexmeasures.io": "2020-04",
  247. }
  248. assert (
  249. build_ea_scheme_and_naming_authority("company.flexmeasures.io")
  250. == "ea1.2020-04.io.flexmeasures.company"
  251. )
  252. assert (
  253. build_ea_scheme_and_naming_authority("company.flexmeasures.io", "1999-12")
  254. == "ea1.1999-12.io.flexmeasures.company"
  255. )
  256. with pytest.raises(Exception, match="adhere to the format"):
  257. build_ea_scheme_and_naming_authority("company.flexmeasures.io", "1999--13")
  258. with pytest.raises(Exception, match="should be in the range"):
  259. build_ea_scheme_and_naming_authority("company.flexmeasures.io", "1999-13")
  260. with pytest.raises(Exception, match="when authority"):
  261. build_ea_scheme_and_naming_authority("company.notflexmeasures.io")