From 0a3abbcbbdac438f4bc33c5934cc0d95942a6f1c Mon Sep 17 00:00:00 2001 From: sgilbride Date: Thu, 22 Aug 2019 16:25:26 -0700 Subject: [PATCH 1/3] Created threshold agent test for python3 --- .../tests/test_threshold_agent.py | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py diff --git a/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py b/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py new file mode 100644 index 0000000000..7eb9b5253b --- /dev/null +++ b/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- {{{ +# vim: set fenc=utf-8 ft=python sw=4 ts=4 sts=4 et: + +# -*- coding: utf-8 -*- {{{ +# vim: set fenc=utf-8 ft=python sw=4 ts=4 sts=4 et: +# +# Copyright 2017, 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 +# }}} +#}}} + +import logging +import sys +import uuid +import unittest +from unittest.mock import Mock +import pytest + +from volttron.platform.vip.agent import Agent, Core, PubSub, RPC, compat +from volttron.platform.agent import utils +from volttron.platform.messaging.health import Status, STATUS_BAD +from volttrontesting.utils.utils import AgentMock +from services.ops.ThresholdDetectionAgent.thresholddetection.agent import ThresholdDetectionAgent + +utils.setup_logging() +_log = logging.getLogger(__name__) +__version__ = '3.7' + + +class TestAgent(unittest.TestCase): + + def setUp(self): + ThresholdDetectionAgent.__bases__ = (AgentMock.imitate(Agent, Agent()), ) + + def test_config(self): + agent = ThresholdDetectionAgent('..\\thresholddetection.config') + assert agent is not None + agent.vip.assert_has_calls(agent.vip.config.set_default('config', 'thresholddetection.config')) + agent.vip.assert_has_calls(agent.vip.config.subscribe(agent._config_add, actions="NEW", pattern="config")) + agent.vip.assert_has_calls(agent.vip.config.subscribe(agent._config_del, actions="DELETE", pattern="config")) + agent.vip.assert_has_calls(agent.vip.config.subscribe(agent._config_mod, actions="UPDATE", pattern="config")) + + def test_alert_high(self): + all_calls = [] + agent = ThresholdDetectionAgent('../thresholddetection.config') + agent._alert('datalogger/log/platform/cpu_percent', 99, 100) + for call in agent.vip.mock_calls: + all_calls.append(call) + assert 'above' in all_calls[4].args[1].context + + def test_alert_low(self): + all_calls = [] + agent = ThresholdDetectionAgent('../thresholddetection.config') + agent._alert('datalogger/log/platform/cpu_percent', 99, 90) + for call in agent.vip.mock_calls: + all_calls.append(call) + assert 'below' in all_calls[4].args[1].context + + +def main(argv=sys.argv): + agent = ThresholdDetectionAgent() + + +if __name__ == '__main__': + # Entry point for script + try: + sys.exit(main()) + except KeyboardInterrupt: + pass From 2b4008b8430b8c78c35532249dcad802993eb73a Mon Sep 17 00:00:00 2001 From: sgilbride Date: Wed, 28 Aug 2019 15:50:59 -0700 Subject: [PATCH 2/3] cleaned up import path --- .../ops/ThresholdDetectionAgent/tests/test_threshold_agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py b/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py index 7eb9b5253b..61e7efb383 100644 --- a/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py +++ b/services/ops/ThresholdDetectionAgent/tests/test_threshold_agent.py @@ -51,7 +51,7 @@ from volttron.platform.agent import utils from volttron.platform.messaging.health import Status, STATUS_BAD from volttrontesting.utils.utils import AgentMock -from services.ops.ThresholdDetectionAgent.thresholddetection.agent import ThresholdDetectionAgent +from thresholddetection.agent import ThresholdDetectionAgent utils.setup_logging() _log = logging.getLogger(__name__) From 95316bc087e04e2c3802ac91e2d530930dc3e958 Mon Sep 17 00:00:00 2001 From: sgilbride Date: Fri, 30 Aug 2019 17:36:24 -0700 Subject: [PATCH 3/3] Added description for MockAgent in utils.py --- volttrontesting/utils/utils.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/volttrontesting/utils/utils.py b/volttrontesting/utils/utils.py index 442fec4b3f..0a115a4bbb 100644 --- a/volttrontesting/utils/utils.py +++ b/volttrontesting/utils/utils.py @@ -179,7 +179,21 @@ def validate_published_device_data(expected_headers, expected_message, class AgentMock(object): - + ''' + The purpose for this parent class is to be used for unit + testing of agents. It takes in the class methods of other + classes, turns them into it's own mock methods. For testing, + dynamically replace the agent's current base class with this + class, while passing in the agent's current classes as arguments. + + For example: + Agent_to_test.__bases__ = (AgentMock.imitate(Agent, Agent()), ) + + As noted in the example, __bases__ takes in a tuple. + Also, the parent class Agent is passed as both Agent and the + instantiated Agent(), since it contains a class within it + that needs to be mocked as well + ''' @classmethod def imitate(cls, *others): for other in others: