diff --git a/.github/workflows/auto-assign-project.yml b/.github/workflows/auto-assign-project.yml new file mode 100644 index 0000000..04ee1c8 --- /dev/null +++ b/.github/workflows/auto-assign-project.yml @@ -0,0 +1,22 @@ +name: Add bugs to bugs project + +on: + issues: + types: + - opened + +jobs: + add-to-project: + name: Add issue to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@v0.3.0 + with: + # You can target a repository in a different organization + # to the issue + project-url: https://github.com/orgs/eclipse-volttron/projects/3 + # project-url: https://github.com/orgs//projects/ + # github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} + github-token: ${{ secrets.AUTO_PROJECT_PAT }} + # labeled: bug, needs-triage + # label-operator: OR diff --git a/.github/workflows/code_analysis.yml b/.github/workflows/code-analysis.yml similarity index 100% rename from .github/workflows/code_analysis.yml rename to .github/workflows/code-analysis.yml diff --git a/.github/workflows/create_release.yml b/.github/workflows/create-release.yml similarity index 100% rename from .github/workflows/create_release.yml rename to .github/workflows/create-release.yml diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish-to-pypi.yml similarity index 100% rename from .github/workflows/publish_to_pypi.yml rename to .github/workflows/publish-to-pypi.yml diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run-tests.yml similarity index 97% rename from .github/workflows/run_tests.yml rename to .github/workflows/run-tests.yml index 56faa19..b090938 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run-tests.yml @@ -28,7 +28,7 @@ jobs: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04] + os: [ubuntu-22.04] python: ['3.8', '3.9', '3.10'] runs-on: ${{ matrix.os }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fc03649..58f5cdd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -59,13 +59,3 @@ repos: entry: yapf language: python types: [python] - - -- repo: local - hooks: - - id: pytest - name: Check pytest unit tests pass - entry: poetry run pytest - pass_filenames: false - language: system - types: [python] diff --git a/README.md b/README.md index 3cb2872..43fcd66 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,13 @@ # volttron-lib-fake-driver -![Passing?](https://github.com/VOLTTRON/volttron-lib-fake-driver/actions/workflows/run_tests.yml/badge.svg) +![Passing?](https://github.com/VOLTTRON/volttron-lib-fake-driver/actions/workflows/run-tests.yml/badge.svg) [![pypi version](https://img.shields.io/pypi/v/volttron-lib-fake-driver.svg)](https://pypi.org/project/volttron-lib-fake-driver/) -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) This project contains Drivers supported and maintained by the Volttron team. # Prerequisites * Python 3.8 -* Poetry 1.2.2 ## Python @@ -33,111 +31,57 @@ pyenv global system 3.8.10 ``` - -## Poetry - -This project uses `poetry` to install and manage dependencies. To install poetry, -follow these [instructions](https://python-poetry.org/docs/master/#installation). - # Installation -With `pip`: +Create and activate a virtual environment. ```shell -python3.8 -m pip install volttron-lib-fake-driver - -# Develop mode -python3.8 -m pip install --editable volttron-lib-fake-driver +python -m venv env +source env/bin/activate ``` -# Development - -## Environment - -Set the environment to be in your project directory: - -```poetry config virtualenvs.in-project true``` - -If you want to install all your dependencies, including dependencies to help with developing your agent, run this command: - -```poetry install``` - -If you want to install only the dependencies needed to run your agent, run this command: - -```poetry install --no-dev``` - -Activate the virtual environment: +Install volttron and start the platform. ```shell -# using Poetry -poetry shell +pip install volttron -# using 'source' command -source "$(poetry env info --path)/bin/activate" +# Start platform with output going to volttron.log +volttron -vv -l volttron.log & ``` -## Source Control - -1. To use git to manage version control, create a new git repository in your local agent project. - -```git init``` - -2. Then create a new repo in your Github or Gitlab account. Copy the URL that points to that new repo in -your Github or Gitlab account. This will be known as our 'remote'. - -3. Add the remote (i.e. the new repo URL from your Github or Gitlab account) to your local repository. Run the following command: - -```git remote add origin ``` - -When you push to your repo, note that the default branch is called 'main'. - +Install the library. You have two options. You can install this library using the version on PyPi: -## Optional Configurations - -### Precommit - -Note: Ensure that you have created the virtual environment using Poetry - -Install pre-commit hooks: - -```poetry run pre-commit install``` - -To run pre-commit on all your files, run this command: - -```poetry run pre-commit run --all-files``` - -If you have precommit installed and you want to ignore running the commit hooks -every time you run a commit, include the `--no-verify` flag in your commit. The following -is an example: - -```git commit -m "Some message" --no-verify``` - - -# Publishing to PyPi +```shell +pip install volttron-lib-fake-driver +``` -Publishing your Driver module to PyPi is automated through the continuous integration workflow provided in `~/.github/workflows/publish_to_pypi.yml`. -You can update that Github Workflow with your credentials to ensure that publishing to PyPi will succeed. The default behavior of -that workflow is to publish to PyPi when a release has been published. If you want to change this behavior, you can modify the -workflow to publish to PyPi based on whatever desired event; see [Github Workflows docs](https://docs.github.com/en/actions/using-workflows/triggering-a-workflow) -on how to change the events that trigger a workflow. +Or you can install the local version of this library from this repo: +```shell +pip install -e . +``` -# Documentation +# Development -To build the docs, navigate to the 'docs' directory and build the documentation: +Please see the following for contributing guidelines [contributing](https://github.com/eclipse-volttron/volttron-core/blob/develop/CONTRIBUTING.md). -```shell -cd docs -make html -``` +Please see the following helpful guide about [developing modular VOLTTRON agents](https://github.com/eclipse-volttron/volttron-core/blob/develop/DEVELOPING_ON_MODULAR.md) -After the documentation is built, view the documentation in html form in your browser. -The html files will be located in `~/docs/build/html`. -**PROTIP: To open the landing page of your documentation directly from the command line, run the following command:** +# Disclaimer Notice -```shell -open /docs/build/html/index.html -``` +This material was prepared as an account of work sponsored by an agency of the +United States Government. Neither the United States Government nor the United +States Department of Energy, nor Battelle, nor any of their employees, nor any +jurisdiction or organization that has cooperated in the development of these +materials, makes any warranty, express or implied, or assumes any legal +liability or responsibility for the accuracy, completeness, or usefulness or any +information, apparatus, product, software, or process disclosed, or represents +that its use would not infringe privately owned rights. -This will open the documentation landing page in your default browsert (e.g. Chrome, Firefox). +Reference herein to any specific commercial product, process, or service by +trade name, trademark, manufacturer, or otherwise does not necessarily +constitute or imply its endorsement, recommendation, or favoring by the United +States Government or any agency thereof, or Battelle Memorial Institute. The +views and opinions of authors expressed herein do not necessarily state or +reflect those of the United States Government or any agency thereof. diff --git a/pyproject.toml b/pyproject.toml index c474c58..349c6c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,10 +27,10 @@ classifiers = [ [tool.poetry.dependencies] python = ">=3.8,<4.0" -volttron-lib-base-driver = "^0.1.1a0" +volttron-lib-base-driver = "^0.1.1a3" [tool.poetry.group.dev.dependencies] -volttron-testing = "^0.3.1a7" +volttron-testing = "^0.3.1a9" pytest = "^6.2.5" pytest-cov = "^3.0.0" mock = "^4.0.3" diff --git a/tests/conftest.py b/tests/conftest.py index 75e13c3..0a1428e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,47 @@ +# -*- coding: utf-8 -*- {{{ +# vim: set fenc=utf-8 ft=python sw=4 ts=4 sts=4 et: +# +# Copyright 2020, Battelle Memorial Institute. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This material was prepared as an account of work sponsored by an agency of +# the United States Government. Neither the United States Government nor the +# United States Department of Energy, nor Battelle, nor any of their +# employees, nor any jurisdiction or organization that has cooperated in the +# development of these materials, makes any warranty, express or +# implied, or assumes any legal liability or responsibility for the accuracy, +# completeness, or usefulness or any information, apparatus, product, +# software, or process disclosed, or represents that its use would not infringe +# privately owned rights. Reference herein to any specific commercial product, +# process, or service by trade name, trademark, manufacturer, or otherwise +# does not necessarily constitute or imply its endorsement, recommendation, or +# favoring by the United States Government or any agency thereof, or +# Battelle Memorial Institute. The views and opinions of authors expressed +# herein do not necessarily state or reflect those of the +# United States Government or any agency thereof. +# +# PACIFIC NORTHWEST NATIONAL LABORATORY operated by +# BATTELLE for the UNITED STATES DEPARTMENT OF ENERGY +# under Contract DE-AC05-76RL01830 +# }}} """Configuration for the pytest test suite.""" +import sys from pathlib import Path -TESTS_DIR = Path(__file__).parent -TMP_DIR = TESTS_DIR / "tmp" -FIXTURES_DIR = TESTS_DIR / "fixtures" +p = Path(__file__) +if p.parent.parent.parent.resolve().as_posix() not in sys.path: + sys.path.insert(0, p.parent.parent.resolve().as_posix()) + +from volttrontesting.fixtures.volttron_platform_fixtures import * diff --git a/tests/test_driver.py b/tests/test_driver.py index 93b44da..d391972 100644 --- a/tests/test_driver.py +++ b/tests/test_driver.py @@ -1,8 +1,128 @@ -"""Unit tests for volttron-lib-fake-driver""" +"""Integration tests for volttron-lib-fake-driver""" -from volttron.driver.interfaces.fake.fake import BaseInterface, Fake +import gevent +import pytest +from volttron.client.known_identities import CONFIGURATION_STORE, PLATFORM_DRIVER +from volttron.utils import jsonapi +from volttrontesting.platformwrapper import PlatformWrapper -def test_driver(): - driver = Fake() - assert isinstance(driver, BaseInterface) +def test_scrape_all(publish_agent): + # add Fake Driver to Platform Driver + registry_config_string = """Point Name,Volttron Point Name,Units,Units Details,Writable,Starting Value,Type,Notes + SampleLong1,SampleLong1,Enumeration,1 through 13,FALSE,50,int,Status indicator of service switch + SampleWritableShort1,SampleWritableShort1,%,0.00 to 100.00 (20 default),TRUE,20,int,Minimum damper position during the standard mode + SampleBool1,SampleBool1,On / Off,on/off,FALSE,TRUE,boolean,Status indidcator of cooling stage 1""" + publish_agent.vip.rpc.call(CONFIGURATION_STORE, + "manage_store", + PLATFORM_DRIVER, + "fake.csv", + registry_config_string, + config_type="csv") + + driver_config = { + "driver_config": {}, + "registry_config": "config://fake.csv", + "interval": 5, + "timezone": "US/Pacific", + "heart_beat_point": "Heartbeat", + "driver_type": "fake" + } + publish_agent.vip.rpc.call(CONFIGURATION_STORE, + "manage_store", + PLATFORM_DRIVER, + "devices/fake", + jsonapi.dumps(driver_config), + config_type='json') + + gevent.sleep(10) + + actual_scrape_all_results = publish_agent.vip.rpc.call(PLATFORM_DRIVER, "scrape_all", + "fake").get(timeout=10) + expected_scrape_all_results = { + 'SampleLong1': 50, + 'SampleBool1': True, + 'SampleWritableShort1': 20 + } + assert actual_scrape_all_results == expected_scrape_all_results + + +def test_get_point_set_point(publish_agent): + actual_sampleWriteableShort1 = publish_agent.vip.rpc.call( + PLATFORM_DRIVER, "get_point", "fake", "SampleWritableShort1").get(timeout=10) + assert actual_sampleWriteableShort1 == 20 + + #set_point + actual_sampleWriteableShort1 = publish_agent.vip.rpc.call(PLATFORM_DRIVER, "set_point", "fake", + "SampleWritableShort1", + 42).get(timeout=10) + assert actual_sampleWriteableShort1 == 42 + actual_sampleWriteableShort1 = publish_agent.vip.rpc.call( + PLATFORM_DRIVER, "get_point", "fake", "SampleWritableShort1").get(timeout=10) + assert actual_sampleWriteableShort1 == 42 + + +@pytest.fixture(scope="module") +def publish_agent(volttron_instance: PlatformWrapper): + assert volttron_instance.is_running() + vi = volttron_instance + assert vi is not None + assert vi.is_running() + + # install platform driver + config = { + "driver_scrape_interval": 0.05, + "publish_breadth_first_all": "false", + "publish_depth_first": "false", + "publish_breadth_first": "false" + } + puid = vi.install_agent(agent_dir="volttron-platform-driver", + config_file=config, + start=False, + vip_identity=PLATFORM_DRIVER) + assert puid is not None + gevent.sleep(1) + assert vi.start_agent(puid) + assert vi.is_agent_running(puid) + + # create the publish agent + publish_agent = volttron_instance.build_agent() + assert publish_agent.core.identity + gevent.sleep(1) + + capabilities = {"edit_config_store": {"identity": PLATFORM_DRIVER}} + volttron_instance.add_capabilities(publish_agent.core.publickey, capabilities) + + # Add Fake Driver to Platform Driver + registry_config_string = """Point Name,Volttron Point Name,Units,Units Details,Writable,Starting Value,Type,Notes + SampleLong1,SampleLong1,Enumeration,1 through 13,FALSE,50,int,Status indicator of service switch + SampleWritableShort1,SampleWritableShort1,%,0.00 to 100.00 (20 default),TRUE,20,int,Minimum damper position during the standard mode + SampleBool1,SampleBool1,On / Off,on/off,FALSE,TRUE,boolean,Status indidcator of cooling stage 1""" + publish_agent.vip.rpc.call(CONFIGURATION_STORE, + "manage_store", + PLATFORM_DRIVER, + "fake.csv", + registry_config_string, + config_type="csv") + + driver_config = { + "driver_config": {}, + "registry_config": "config://fake.csv", + "interval": 5, + "timezone": "US/Pacific", + "heart_beat_point": "Heartbeat", + "driver_type": "fake" + } + publish_agent.vip.rpc.call(CONFIGURATION_STORE, + "manage_store", + PLATFORM_DRIVER, + "devices/fake", + jsonapi.dumps(driver_config), + config_type='json') + + gevent.sleep(10) + + yield publish_agent + + volttron_instance.stop_agent(puid) + publish_agent.core.stop()