Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test to PVForecast #174

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

b0661
Copy link
Contributor

@b0661 b0661 commented Oct 16, 2024

Tests were added for PVForecast

To improve testability several steps were done. Coverage currently is around 85%.

  • Documentation of the module
  • Addition of type hints where possible
  • Separation, test and use of common utility functions to allow for general testing at one spot.
    • to_datetime
    • CacheFileStore
  • Use of logging instead of print to easily capture in testing.
  • Add validation of the json schema for Akkudoktor PV forecast data.
  • Allow to create an empty PVForecast instance as base instance for testing.
  • Make process_data() complete for filling a PVForecast instance for testing.
  • Normalize forecast datetime to timezone of system given in loaded data.
  • Do not print forecast data report but provide report for test checks.
  • Get rid of cache file path using the CachFileStore to automate cache file usage.

Added documentation. Beware mostly generated by ChatGPT.

Signed-off-by: Bobby Noelte <[email protected]>
@Lasall
Copy link
Contributor

Lasall commented Oct 16, 2024

When we change to fastapi, we will use pydantic. Maybe we could replace the jsonschema with pydantic here.

@b0661 b0661 force-pushed the pr_pv_forecast_on_main branch 4 times, most recently from 47f08d0 to 93db87b Compare October 16, 2024 15:54
@b0661
Copy link
Contributor Author

b0661 commented Oct 16, 2024

When we change to fastapi, we will use pydantic. Maybe we could replace the jsonschema with pydantic here.

Switched to pydantic.

Copy link
Contributor

@Lasall Lasall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think currently only the url is used to fill PVForecast with data (/pvforecast). So to me the interface seems complicated supporting data (dict), filepath and url. If we want to support filepath and raw data input to the class maybe we should abstract filepath, url into PVForecastFile, PVForecastURL to do the io/network stuff (maybe one more abstraction layer for the caching) and then have the base class with all the logic operating directly on the raw data (e.g. process_data does not require any input, that's not already defined in base constructor).

src/akkudoktoreos/class_pv_forecast.py Outdated Show resolved Hide resolved
self.meta = {}
self.forecast_data = []
self.cache_dir = cache_dir
self.prediction_hours = prediction_hours
self.cache_files = CacheFileStore()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For retrieving forecast data could we maybe use lru_cache from functools?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about cachetools TTLCache? Seems to be what is intended in the current code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at cachetools and filecache and some other. They were missing some aspects I wanted to have. Will stay with CacheFileStore but added a function decorator cache_in_file() to make it quite easy to cache function return values.

    @cache_in_file(mode="wb+")
    def load_data_from_url_with_caching(self, url: str) -> dict:
        response = requests.get(url)
        data = response.json()
        logger.debug(f"Data fetched from URL `{url} and cached.")
        return data

data = pv_forecast.load_data_from_url_with_caching(url, with_ttl="2 days")

@b0661
Copy link
Contributor Author

b0661 commented Oct 17, 2024

I think currently only the url is used to fill PVForecast with data (/pvforecast). So to me the interface seems complicated supporting data (dict), filepath and url. If we want to support filepath and raw data input to the class maybe we should abstract filepath, url into PVForecastFile, PVForecastURL to do the io/network stuff (maybe one more abstraction layer for the caching) and then have the base class with all the logic operating directly on the raw data (e.g. process_data does not require any input, that's not already defined in base constructor).

You are right. Doing this would radically change the interface. I would do that in a following PR if this one is accepted.

@b0661 b0661 force-pushed the pr_pv_forecast_on_main branch 2 times, most recently from 4c99bcf to d9cdf3a Compare October 17, 2024 19:33
The `CacheFileStore` class is a singleton-based, thread-safe key-value store for managing
temporary file objects, allowing the creation, retrieval, and management of cache files.

The utility modules offer a flexible logging setup (`get_logger`) and utilities to handle
different date-time formats (`to_datetime`, `to_timestamp`).

- Cache files are automatically valid for the the current date unless specified otherwise.
  This is to mimic the current behaviour used in several classes.
- The logger supports rotating log files to prevent excessive log file size.
- The `to_datetime` and `to_timestamp`functions support a wide variety of input types and formats.
  They provide the time conversion that is e.g. used in PVForecast.

Signed-off-by: Bobby Noelte <[email protected]>
Improvements for testing of PVForecast
- Use common utility functions to allow for general testing at one spot.
  - to_datetime
  - CacheFileStore
- Use logging instead of print to easily capture in testing.
- Add validation of the json schema for Akkudoktor PV forecast data.
- Allow to create an empty PVForecast instance as base instance for testing.
- Make process_data() complete for filling a PVForecast instance for testing.
- Normalize forecast datetime to timezone of system given in loaded data.
- Do not print report but provide report for test checks.
- Get rid of cache file path using the CachFileStore to automate cache file usage.
- Improved module documentation.

Signed-off-by: Bobby Noelte <[email protected]>
- Add test for PVForecast
- Add test for CacheFileStore in the new cachefilestore module
- Add test for to_datetime in the new datetimeutil module
- Add test for get_logger in the new logutil module

Signed-off-by: Bobby Noelte <[email protected]>
@drbacke
Copy link
Contributor

drbacke commented Oct 22, 2024

Please re-run all tests, code changed quite a lot

1 similar comment
@drbacke
Copy link
Contributor

drbacke commented Oct 22, 2024

Please re-run all tests, code changed quite a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants