test_reporting.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. from flexmeasures.data.schemas.reporting.pandas_reporter import (
  2. PandasReporterConfigSchema,
  3. PandasReporterParametersSchema,
  4. )
  5. from flexmeasures.data.schemas.reporting.profit import (
  6. ProfitOrLossReporterConfigSchema,
  7. ProfitOrLossReporterParametersSchema,
  8. )
  9. from marshmallow.exceptions import ValidationError
  10. import pytest
  11. @pytest.mark.parametrize(
  12. "config, is_valid",
  13. [
  14. (
  15. { # this checks that the final_df_output dataframe is actually generated at some point of the processing pipeline
  16. "required_input": [{"name": "sensor_1"}],
  17. "required_output": [{"name": "final_output"}],
  18. "transformations": [
  19. {
  20. "df_output": "final_output",
  21. "df_input": "sensor_1",
  22. "method": "copy",
  23. }
  24. ],
  25. },
  26. True,
  27. ),
  28. (
  29. { # this checks that chaining works, applying the method copy on the previous dataframe
  30. "required_input": [{"name": "sensor_1"}],
  31. "required_output": [{"name": "final_output"}],
  32. "transformations": [
  33. {"df_output": "output1", "df_input": "sensor_1", "method": "copy"},
  34. {"method": "copy"},
  35. {"df_output": "final_output", "method": "copy"},
  36. ],
  37. },
  38. True,
  39. ),
  40. (
  41. { # this checks that resample cannot be the last method being applied
  42. "required_input": [{"name": "sensor_1"}, {"name": "sensor_2"}],
  43. "required_output": [{"name": "final_output"}],
  44. "transformations": [
  45. {"df_output": "output1", "df_input": "sensor_1", "method": "copy"},
  46. {"method": "copy"},
  47. {"df_output": "final_output", "method": "resample", "args": ["1h"]},
  48. ],
  49. },
  50. False,
  51. ),
  52. (
  53. { # this checks that resample cannot be the last method being applied
  54. "required_input": [{"name": "sensor_1"}, {"name": "sensor_2"}],
  55. "required_output": [{"name": "final_output"}],
  56. "transformations": [
  57. {"df_output": "output1", "df_input": "sensor_1", "method": "copy"},
  58. {"method": "copy"},
  59. {"df_output": "final_output", "method": "resample", "args": ["1h"]},
  60. {"method": "asfreq"},
  61. ],
  62. },
  63. True,
  64. ),
  65. ],
  66. )
  67. def test_pandas_reporter_config_schema(config, is_valid, db, app, setup_dummy_sensors):
  68. schema = PandasReporterConfigSchema()
  69. if is_valid:
  70. schema.load(config)
  71. else:
  72. with pytest.raises(ValidationError):
  73. schema.load(config)
  74. @pytest.mark.parametrize(
  75. "parameters, is_valid",
  76. [
  77. (
  78. {
  79. "input": [
  80. {
  81. "name": "sensor_1_df",
  82. "sensor": 1,
  83. } # we're describing how the named variables should be constructed, by defining search filters on the sensor data, rather than on the sensor
  84. ],
  85. "output": [
  86. {"name": "df2", "sensor": 2}
  87. ], # sensor to save the output to
  88. "start": "2023-06-06T00:00:00+02:00",
  89. "end": "2023-06-06T00:00:00+02:00",
  90. },
  91. True,
  92. ),
  93. ( # missing start and end
  94. {
  95. "input": [{"name": "sensor_1_df", "sensor": 1}],
  96. "output": [{"name": "df2", "sensor": 2}],
  97. },
  98. False,
  99. ),
  100. (
  101. {
  102. "input": [
  103. {
  104. "name": "sensor_1_df",
  105. "sensor": 1,
  106. "event_starts_after": "2023-06-07T00:00:00+02:00",
  107. "event_ends_before": "2023-06-07T00:00:00+02:00",
  108. }
  109. ],
  110. "output": [
  111. {"name": "df2", "sensor": 2}
  112. ], # sensor to save the output to
  113. },
  114. True,
  115. ),
  116. ],
  117. )
  118. def test_pandas_reporter_parameters_schema(
  119. parameters, is_valid, db, app, setup_dummy_sensors
  120. ):
  121. schema = PandasReporterParametersSchema()
  122. if is_valid:
  123. schema.load(parameters)
  124. else:
  125. with pytest.raises(ValidationError):
  126. schema.load(parameters)
  127. @pytest.mark.parametrize(
  128. "config, is_valid",
  129. [
  130. ( # missing start and end
  131. {
  132. "consumption_price_sensor": 2,
  133. "production_price_sensor": 2,
  134. },
  135. True,
  136. ),
  137. (
  138. {
  139. "consumption_price_sensor": 2,
  140. },
  141. True,
  142. ),
  143. (
  144. {
  145. "production_price_sensor": 2,
  146. },
  147. True,
  148. ),
  149. (
  150. {},
  151. False,
  152. ),
  153. ],
  154. )
  155. def test_profit_reporter_config_schema(config, is_valid, db, app, setup_dummy_sensors):
  156. schema = ProfitOrLossReporterConfigSchema()
  157. if is_valid:
  158. schema.load(config)
  159. else:
  160. with pytest.raises(ValidationError):
  161. schema.load(config)
  162. start = "2023-01-01T00:00:00+01:00"
  163. end = "2023-01-02T00:00:00+01:00"
  164. @pytest.mark.parametrize(
  165. "parameters, is_valid",
  166. [
  167. (
  168. {
  169. "input": [{"sensor": 1}], # unit: MWh
  170. "output": [{"sensor": 3}], # unit : EUR
  171. "start": start,
  172. "end": end,
  173. },
  174. True,
  175. ),
  176. (
  177. {
  178. "input": [{"sensor": 4}], # unit: MW
  179. "output": [{"sensor": 3}], # unit : EUR
  180. "start": start,
  181. "end": end,
  182. },
  183. True,
  184. ),
  185. ( # wrong output unit
  186. {
  187. "input": [{"sensor": 4}], # unit: MW
  188. "output": [{"sensor": 4}], # unit : MW
  189. "start": start,
  190. "end": end,
  191. },
  192. False,
  193. ),
  194. ( # wrong input unit
  195. {
  196. "input": [{"sensor": 3}], # unit: EUR
  197. "output": [{"sensor": 3}], # unit : EUR
  198. "start": start,
  199. "end": end,
  200. },
  201. False,
  202. ),
  203. ],
  204. )
  205. def test_profit_reporter_parameters_schema(
  206. parameters, is_valid, db, app, setup_dummy_sensors
  207. ):
  208. schema = ProfitOrLossReporterParametersSchema()
  209. if is_valid:
  210. schema.load(parameters)
  211. else:
  212. with pytest.raises(ValidationError):
  213. schema.load(parameters)