From ec85a41c97e13c315e7877b401933b493dd0287a Mon Sep 17 00:00:00 2001 From: "C. Allwardt" <3979063+craig8@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:21:09 -0700 Subject: [PATCH] rebase pubsub fixes --- src/volttron/client/logs.py | 16 + .../client/vip/agent/subsystems/rpc.py | 8 +- src/volttron/server/logs.py | 3 +- src/volttron/types/auth/authz_types.py | 5 +- src/volttron/utils/__init__.py | 4 +- tests/unit/test_aip.py | 19 - tests/unit/test_authz_model.py | 743 +++++++++++------- tests/unit/test_subsystems.py | 60 -- tests/unit/utils/test_environment_vars.py | 60 -- tests/unit/utils/test_keystore.py | 129 --- tests/unit/utils/test_load_utils.py | 12 +- 11 files changed, 505 insertions(+), 554 deletions(-) delete mode 100644 tests/unit/test_aip.py delete mode 100644 tests/unit/test_subsystems.py delete mode 100644 tests/unit/utils/test_environment_vars.py delete mode 100644 tests/unit/utils/test_keystore.py diff --git a/src/volttron/client/logs.py b/src/volttron/client/logs.py index 6e93f7e1a..8035063d2 100644 --- a/src/volttron/client/logs.py +++ b/src/volttron/client/logs.py @@ -1,5 +1,7 @@ import logging from logging import Logger +import sys +import os def get_logger() -> Logger: @@ -43,6 +45,18 @@ def get_default_client_log_config(level=logging.DEBUG) -> dict: } +class JsonFormatter(logging.Formatter): + + def format(self, record): + dct = record.__dict__.copy() + dct["msg"] = record.getMessage() + dct.pop("args") + exc_info = dct.pop("exc_info", None) + if exc_info: + dct["exc_text"] = "".join(traceback.format_exception(*exc_info)) + return jsonapi.dumps(dct) + + class AgentFormatter(logging.Formatter): def __init__(self, fmt=None, datefmt=None): @@ -66,6 +80,8 @@ def format(self, record): def setup_logging(level=logging.DEBUG, console=False): + from volttron.utils.commands import isapipe + root = logging.getLogger() if not root.handlers: handler = logging.StreamHandler() diff --git a/src/volttron/client/vip/agent/subsystems/rpc.py b/src/volttron/client/vip/agent/subsystems/rpc.py index 6adc0dcf0..d07d22994 100644 --- a/src/volttron/client/vip/agent/subsystems/rpc.py +++ b/src/volttron/client/vip/agent/subsystems/rpc.py @@ -35,7 +35,7 @@ from zmq import ZMQError from zmq.green import ENOTSOCK -from volttron.auth.auth_exception import AuthException +#from volttron.auth.auth_exception import AuthException from volttron.utils import jsonapi, jsonrpc from volttron.client.known_identities import AUTH @@ -265,8 +265,10 @@ def checked_method(*args, **kwargs): method_name = method.__name__ args_dict = inspect.getcallargs(method, *args, **kwargs) try: - self.call(AUTH, "check_authorization", - identity=calling_user, method_name=f"{self.core.identity}.{method_name}", + self.call(AUTH, + "check_authorization", + identity=calling_user, + method_name=f"{self.core.identity}.{method_name}", method_args=args_dict).get(timeout=10) except AuthException as e: # msg = ("method '{}' requires capabilities {}, but capability {} " diff --git a/src/volttron/server/logs.py b/src/volttron/server/logs.py index 43c5156d7..4126337aa 100644 --- a/src/volttron/server/logs.py +++ b/src/volttron/server/logs.py @@ -26,8 +26,6 @@ import logging import os -from volttron.client.logs import AgentFormatter - # -*- coding: utf-8 -*- {{{ # ===----------------------------------------------------------------------=== # @@ -62,6 +60,7 @@ import warnings from volttron.utils import jsonapi +from volttron.client.logs import AgentFormatter try: HAS_SYSLOG = True diff --git a/src/volttron/types/auth/authz_types.py b/src/volttron/types/auth/authz_types.py index 5d5b3c863..8bc0f247c 100644 --- a/src/volttron/types/auth/authz_types.py +++ b/src/volttron/types/auth/authz_types.py @@ -607,9 +607,8 @@ def create_or_merge_role(self, rpc_capabilities: RPCCapabilities = None, pubsub_capabilities: PubsubCapabilities = None) -> bool: if not rpc_capabilities and not pubsub_capabilities: - raise ValueError( - f"Role {name} should have non empty capabilities - __rpc__ capabilities, " - "pubsub capabilities or both") + raise ValueError(f"Role {name} should have non empty capabilities - rpc capabilities, " + "pubsub capabilities or both") if not self.compact_dict.get(ROLES): self.compact_dict[ROLES] = dict() if name not in self.compact_dict.get(ROLES): diff --git a/src/volttron/utils/__init__.py b/src/volttron/utils/__init__.py index c9c48bfa7..07a1a6c93 100644 --- a/src/volttron/utils/__init__.py +++ b/src/volttron/utils/__init__.py @@ -51,8 +51,6 @@ from volttron.utils.version import get_version from volttron.types import Identity -from volttron.client.logs import setup_logging - _log = logging.getLogger(__name__) @@ -92,7 +90,7 @@ def load_config(default_configuration: str | Path | dict | None) -> dict: :rtype: dict """ - if default_configuration is None: + if default_configuration is None or default_configuration == "": return {} if isinstance(default_configuration, dict): diff --git a/tests/unit/test_aip.py b/tests/unit/test_aip.py deleted file mode 100644 index 31a0afb70..000000000 --- a/tests/unit/test_aip.py +++ /dev/null @@ -1,19 +0,0 @@ -from dataclasses import dataclass - -from volttron.server.aip import AIPplatform - - -@dataclass -class Env: - volttron_home: str = "/tmp/tmp" - - -opt = Env() - - -def test_aip_agent_subpath(): - - aip = AIPplatform(opt) - install_dir = aip.install_dir - path = aip.get_subpath('foo', "bar") - assert f"{install_dir}/foo/bar" == path \ No newline at end of file diff --git a/tests/unit/test_authz_model.py b/tests/unit/test_authz_model.py index c71e8242c..939033d5c 100644 --- a/tests/unit/test_authz_model.py +++ b/tests/unit/test_authz_model.py @@ -1,3 +1,5 @@ +from pathlib import Path + import pytest import json import volttron.types.auth.authz_types as authz @@ -65,8 +67,8 @@ def test_rpc_capabilities(): def test_expand_user_capabilities_on_init(): - with open("input.json") as f: - input_dict = json.load(f) + with Path(__file__).parent / "input.json" as f: + input_dict = json.load(f.open("r")) volttron_authz_map = authz.VolttronAuthzMap.from_unstructured_dict(input_dict) assert volttron_authz_map.compact_dict == input_dict @@ -96,8 +98,10 @@ def test_expand_user_capabilities_on_init(): # } # } # ] - assert (volttron_authz_map.user_capabilities["historian1"]["pubsub_capabilities"] == - {'historian_stats/*': 'publish', 'user_pubsub_topic': 'pubsub'}) + assert (volttron_authz_map.user_capabilities["historian1"]["pubsub_capabilities"] == { + 'historian_stats/*': 'publish', + 'user_pubsub_topic': 'pubsub' + }) # rpc capabilities must have both user groups' capabilities and role's capabilities # role 'edit_config_store' in input json is @@ -110,13 +114,21 @@ def test_expand_user_capabilities_on_init(): # } # above should have got applied with param restriction - assert (volttron_authz_map.user_capabilities["historian1"]["rpc_capabilities"] == - ["agent1.rpc1", - {'config.store.add_config': {'id': 'historian1'}}, - {'config.store.delete_config': {'id': 'historian1'}}, - {'config.store.edit_config': {'id': 'historian1'}} - ] - ) + assert (volttron_authz_map.user_capabilities["historian1"]["rpc_capabilities"] == [ + "agent1.rpc1", { + 'config.store.add_config': { + 'id': 'historian1' + } + }, { + 'config.store.delete_config': { + 'id': 'historian1' + } + }, { + 'config.store.edit_config': { + 'id': 'historian1' + } + } + ]) def test_create_user_simple(): @@ -133,12 +145,13 @@ def test_create_role_simple(): authz_map.create_or_merge_role(name="new_role") assert False except ValueError as e: - assert e.args[0] == ("Role new_role should have non empty capabilities - rpc capabilities, " - "pubsub capabilities or both") + assert e.args[0] == ( + "Role new_role should have non empty capabilities - rpc capabilities, " + "pubsub capabilities or both") authz_map.create_or_merge_role(name="new_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) assert authz_map.compact_dict.get("roles").get("new_role") == {"rpc_capabilities": ["id.rpc1"]} @@ -157,66 +170,95 @@ def test_create_user_groups_simple(): authz_map.create_or_merge_user_group(name="group1", identities=["test_agent"]) assert False except ValueError as e: - assert e.args[0] == ("User group group1 should have non empty capabilities. Please pass non empty values " - "for at least one of the three parameters - roles, rpc_capabilities, pubsub_capabilities") + assert e.args[0] == ( + "User group group1 should have non empty capabilities. Please pass non empty values " + "for at least one of the three parameters - roles, rpc_capabilities, pubsub_capabilities" + ) authz_map.create_or_merge_user_authz(identity="test_agent", comments="Created as part of test") assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} authz_map.create_or_merge_role(name="test_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) # todo test invalid role name - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")])) + authz_map.create_or_merge_user_group(name="group2", + identities=["test_agent"], + roles=authz.UserRoles( + [authz.UserRole(role_name="test_role")])) # compact_dict which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1"]} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1"] + } def test_update_role(): authz_map = authz.VolttronAuthzMap() authz_map.create_or_merge_role(name="new_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) assert authz_map.compact_dict.get("roles").get("new_role") == {"rpc_capabilities": ["id.rpc1"]} # create user with above role - authz_map.create_or_merge_user_authz(identity="test_agent", - roles=authz.UserRoles(user_roles=[authz.UserRole(role_name="new_role")]) - ) + authz_map.create_or_merge_user_authz( + identity="test_agent", + roles=authz.UserRoles(user_roles=[authz.UserRole(role_name="new_role")])) # add pubsub_cap to existing role authz_map.create_or_merge_role(name="new_role", - pubsub_capabilities=authz.PubsubCapabilities( - [authz.PubsubCapability(topic_pattern="test/topic/*", topic_access="pubsub")]) - ) - - assert authz_map.compact_dict.get("roles").get("new_role") == {"rpc_capabilities": ["id.rpc1"], - "pubsub_capabilities": {"test/topic/*": "pubsub"}} + pubsub_capabilities=authz.PubsubCapabilities([ + authz.PubsubCapability(topic_pattern="test/topic/*", + topic_access="pubsub") + ])) + + assert authz_map.compact_dict.get("roles").get("new_role") == { + "rpc_capabilities": ["id.rpc1"], + "pubsub_capabilities": { + "test/topic/*": "pubsub" + } + } # update existing role's pubsub cap authz_map.create_or_merge_role(name="new_role", - pubsub_capabilities=authz.PubsubCapabilities( - [authz.PubsubCapability(topic_pattern="test/topic/*", topic_access="publish")]) - ) - assert authz_map.compact_dict.get("roles").get("new_role") == {"rpc_capabilities": ["id.rpc1"], - "pubsub_capabilities": {"test/topic/*": "publish"}} + pubsub_capabilities=authz.PubsubCapabilities([ + authz.PubsubCapability(topic_pattern="test/topic/*", + topic_access="publish") + ])) + assert authz_map.compact_dict.get("roles").get("new_role") == { + "rpc_capabilities": ["id.rpc1"], + "pubsub_capabilities": { + "test/topic/*": "publish" + } + } # update existing role's rpc cap authz_map.create_or_merge_role(name="new_role", - rpc_capabilities=authz.RPCCapabilities( - [authz.RPCCapability(resource="id.rpc1", param_restrictions={"param1": "val1"})]) - ) - assert authz_map.compact_dict.get("roles")["new_role"]["rpc_capabilities"] == [{"id.rpc1": {"param1": "val1"}}] - assert authz_map.compact_dict.get("roles")["new_role"]["pubsub_capabilities"] == {"test/topic/*": "publish"} + rpc_capabilities=authz.RPCCapabilities([ + authz.RPCCapability(resource="id.rpc1", + param_restrictions={"param1": "val1"}) + ])) + assert authz_map.compact_dict.get("roles")["new_role"]["rpc_capabilities"] == [{ + "id.rpc1": { + "param1": "val1" + } + }] + assert authz_map.compact_dict.get("roles")["new_role"]["pubsub_capabilities"] == { + "test/topic/*": "publish" + } # test if the expanded user_capabilities has been updated based on the new role updates - assert authz_map.user_capabilities["test_agent"]["rpc_capabilities"] == [{"id.rpc1": {"param1": "val1"}}] - assert authz_map.user_capabilities["test_agent"]["pubsub_capabilities"] == {"test/topic/*": "publish"} + assert authz_map.user_capabilities["test_agent"]["rpc_capabilities"] == [{ + "id.rpc1": { + "param1": "val1" + } + }] + assert authz_map.user_capabilities["test_agent"]["pubsub_capabilities"] == { + "test/topic/*": "publish" + } def test_update_user_groups(): @@ -227,164 +269,269 @@ def test_update_user_groups(): authz_map.create_or_merge_user_authz(identity="test_agent", comments="Created as part of test") assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} - authz_map.create_or_merge_user_authz(identity="test_agent2", comments="Created as part of test") + authz_map.create_or_merge_user_authz(identity="test_agent2", + comments="Created as part of test") authz_map.create_or_merge_role(name="test_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) # create user group with users and role - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")])) + authz_map.create_or_merge_user_group(name="group2", + identities=["test_agent"], + roles=authz.UserRoles( + [authz.UserRole(role_name="test_role")])) # compact_dict which gets persisted shouldn't get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": ["test_role"]} + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": ["test_role"] + } assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1"]} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1"] + } ############## # test updates ############## # #1. Update user group add rpc_capabilities - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), - rpc_capabilities=authz.RPCCapabilities( - [authz.RPCCapability(resource="id2.rpc2")] - )) + authz_map.create_or_merge_user_group( + name="group2", + identities=["test_agent"], + roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), + rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability(resource="id2.rpc2")])) # compact_dict user_groups should get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": ["test_role"], - "rpc_capabilities": ["id2.rpc2"] - } + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": ["test_role"], + "rpc_capabilities": ["id2.rpc2"] + } # compact_dict users which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1", "id2.rpc2"]} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1", "id2.rpc2"] + } # #2. Update user group add pubsub_capabilities - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), - rpc_capabilities=authz.RPCCapabilities( - [authz.RPCCapability(resource="id2.rpc2")] - ), - pubsub_capabilities=authz.PubsubCapabilities( - [authz.PubsubCapability(topic_access="publish", topic_pattern="devices/")] - )) + authz_map.create_or_merge_user_group( + name="group2", + identities=["test_agent"], + roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), + rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability(resource="id2.rpc2")]), + pubsub_capabilities=authz.PubsubCapabilities( + [authz.PubsubCapability(topic_access="publish", topic_pattern="devices/")])) # compact_dict user_groups should get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": ["test_role"], - "rpc_capabilities": ["id2.rpc2"], - "pubsub_capabilities": {"devices/": "publish"} - } + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": ["test_role"], + "rpc_capabilities": ["id2.rpc2"], + "pubsub_capabilities": { + "devices/": "publish" + } + } # compact_dict which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1", "id2.rpc2"], - "pubsub_capabilities": {"devices/": "publish"}} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1", "id2.rpc2"], + "pubsub_capabilities": { + "devices/": "publish" + } + } # #3. Update user group current pubsub_capabilities - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), - rpc_capabilities=authz.RPCCapabilities( - [authz.RPCCapability(resource="id2.rpc2")] - ), - pubsub_capabilities=authz.PubsubCapabilities( - [authz.PubsubCapability(topic_access="subscribe", - topic_pattern="devices/")] - )) + authz_map.create_or_merge_user_group( + name="group2", + identities=["test_agent"], + roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), + rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability(resource="id2.rpc2")]), + pubsub_capabilities=authz.PubsubCapabilities( + [authz.PubsubCapability(topic_access="subscribe", topic_pattern="devices/")])) # compact_dict user_groups should get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": ["test_role"], - "rpc_capabilities": ["id2.rpc2"], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": ["test_role"], + "rpc_capabilities": ["id2.rpc2"], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # compact_dict which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1", "id2.rpc2"], - "pubsub_capabilities": {"devices/": "subscribe"}} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1", "id2.rpc2"], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # #4. Update user group current rpc_capabilities - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), - rpc_capabilities=authz.RPCCapabilities( - [authz.RPCCapability(resource="id2.rpc2", param_restrictions={"p1": "v1"})] - )) + authz_map.create_or_merge_user_group( + name="group2", + identities=["test_agent"], + roles=authz.UserRoles([authz.UserRole(role_name="test_role")]), + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability(resource="id2.rpc2", param_restrictions={"p1": "v1"})])) # compact_dict user_groups should get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": ["test_role"], - "rpc_capabilities": [{"id2.rpc2": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": ["test_role"], + "rpc_capabilities": [{ + "id2.rpc2": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # compact_dict users which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1", - {"id2.rpc2": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1", { + "id2.rpc2": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # #5. Update user group current roles - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role", - param_restrictions={"p1": "v1"})]), - rpc_capabilities=authz.RPCCapabilities( - [authz.RPCCapability(resource="id2.rpc2", param_restrictions={"p1": "v1"})] - )) + authz_map.create_or_merge_user_group(name="group2", + identities=["test_agent"], + roles=authz.UserRoles([ + authz.UserRole(role_name="test_role", + param_restrictions={"p1": "v1"}) + ]), + rpc_capabilities=authz.RPCCapabilities([ + authz.RPCCapability(resource="id2.rpc2", + param_restrictions={"p1": "v1"}) + ])) # compact_dict user_groups should get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": [{"test_role": {"p1": "v1"}}], - "rpc_capabilities": [{"id2.rpc2": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": [{ + "test_role": { + "p1": "v1" + } + }], + "rpc_capabilities": [{ + "id2.rpc2": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # compact_dict users which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": [{"test_role": {"p1": "v1"}}], - "rpc_capabilities": [{"id.rpc1": {"p1": "v1"}}, - {"id2.rpc2": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": [{ + "test_role": { + "p1": "v1" + } + }], + "rpc_capabilities": [{ + "id.rpc1": { + "p1": "v1" + } + }, { + "id2.rpc2": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # #6. Update user group current identities authz_map.create_or_merge_user_group(name="group2", identities=["test_agent", "test_agent2"]) # compact_dict user_groups should get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent2", "test_agent"], - "roles": [{"test_role": {"p1": "v1"}}], - "rpc_capabilities": [{"id2.rpc2": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent2", "test_agent"], + "roles": [{ + "test_role": { + "p1": "v1" + } + }], + "rpc_capabilities": [{ + "id2.rpc2": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # compact_dict users which gets persisted shouldn't get updated assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} - assert authz_map.compact_dict["users"]["test_agent2"] == {"comments": "Created as part of test"} + assert authz_map.compact_dict["users"]["test_agent2"] == { + "comments": "Created as part of test" + } # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": [{"test_role": {"p1": "v1"}}], - "rpc_capabilities": [{"id.rpc1": {"p1": "v1"}}, - {"id2.rpc2": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": [{ + "test_role": { + "p1": "v1" + } + }], + "rpc_capabilities": [{ + "id.rpc1": { + "p1": "v1" + } + }, { + "id2.rpc2": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent2"] == {"comments": "Created as part of test", - "roles": [{"test_role": {"p1": "v1"}}], - "rpc_capabilities": [{"id2.rpc2": {"p1": "v1"}}, - {"id.rpc1": {"p1": "v1"}}], - "pubsub_capabilities": {"devices/": "subscribe"} - } + assert authz_map.user_capabilities["test_agent2"] == { + "comments": "Created as part of test", + "roles": [{ + "test_role": { + "p1": "v1" + } + }], + "rpc_capabilities": [{ + "id2.rpc2": { + "p1": "v1" + } + }, { + "id.rpc1": { + "p1": "v1" + } + }], + "pubsub_capabilities": { + "devices/": "subscribe" + } + } def test_update_user(): @@ -399,85 +546,113 @@ def test_update_user(): # #2. create role authz_map.create_or_merge_role(name="test_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) authz_map.create_or_merge_role(name="test_role2", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id3.rpc3")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id3.rpc3")])) # #3. create user group with users and role - authz_map.create_or_merge_user_group(name="group2", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")])) + authz_map.create_or_merge_user_group(name="group2", + identities=["test_agent"], + roles=authz.UserRoles( + [authz.UserRole(role_name="test_role")])) # compact_dict which gets persisted shouldn't get updated - assert authz_map.compact_dict["user_groups"]["group2"] == {"identities": ["test_agent"], - "roles": ["test_role"]} + assert authz_map.compact_dict["user_groups"]["group2"] == { + "identities": ["test_agent"], + "roles": ["test_role"] + } assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1"]} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1"] + } # Test updates to user test_agent # #1. add new role to user authz_map.create_or_merge_user_authz(identity="test_agent", - roles=authz.UserRoles([authz.UserRole(role_name="test_role2")])) + roles=authz.UserRoles( + [authz.UserRole(role_name="test_role2")])) - assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role2"]} + assert authz_map.compact_dict["users"]["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role2"] + } # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role2", "test_role"], - "rpc_capabilities": ["id3.rpc3", "id.rpc1"]} + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role2", "test_role"], + "rpc_capabilities": ["id3.rpc3", "id.rpc1"] + } # #2. add new rpc_capability to user - authz_map.create_or_merge_user_authz(identity="test_agent", - rpc_capabilities=authz.RPCCapabilities([ - authz.RPCCapability(resource="agent2.rpc2", - param_restrictions={'param1': 'value2'})])) + authz_map.create_or_merge_user_authz( + identity="test_agent", + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability(resource="agent2.rpc2", param_restrictions={'param1': + 'value2'})])) # persisted dict should be updated - assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role2"], - "rpc_capabilities": [ - {"agent2.rpc2": {'param1': 'value2'}}]} + assert authz_map.compact_dict["users"]["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role2"], + "rpc_capabilities": [{ + "agent2.rpc2": { + 'param1': 'value2' + } + }] + } # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role2", "test_role"], - "rpc_capabilities": [ - {"agent2.rpc2": {'param1': 'value2'}}, - "id3.rpc3", - "id.rpc1"] - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role2", "test_role"], + "rpc_capabilities": [{ + "agent2.rpc2": { + 'param1': 'value2' + } + }, "id3.rpc3", "id.rpc1"] + } # #3. add new pubsub_capability to user authz_map.create_or_merge_user_authz(identity="test_agent", pubsub_capabilities=authz.PubsubCapabilities([ authz.PubsubCapability(topic_pattern="mytopic/*", topic_access="subscribe") - ]) - ) + ])) # persisted dict should be updated - assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role2"], - "rpc_capabilities": [ - {"agent2.rpc2": {'param1': 'value2'}}], - "pubsub_capabilities": {"mytopic/*": "subscribe"} - } + assert authz_map.compact_dict["users"]["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role2"], + "rpc_capabilities": [{ + "agent2.rpc2": { + 'param1': 'value2' + } + }], + "pubsub_capabilities": { + "mytopic/*": "subscribe" + } + } # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role2", "test_role"], - "rpc_capabilities": [ - {"agent2.rpc2": {'param1': 'value2'}}, - "id3.rpc3", - "id.rpc1"], - "pubsub_capabilities": {"mytopic/*": "subscribe"} - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role2", "test_role"], + "rpc_capabilities": [{ + "agent2.rpc2": { + 'param1': 'value2' + } + }, "id3.rpc3", "id.rpc1"], + "pubsub_capabilities": { + "mytopic/*": "subscribe" + } + } # #4. add new protected_rpcs to user authz_map.create_or_merge_user_authz(identity="test_agent", @@ -485,26 +660,31 @@ def test_update_user(): pubsub_capabilities=authz.PubsubCapabilities([ authz.PubsubCapability(topic_pattern="mytopic/*", topic_access="subscribe") - ]) - ) + ])) # persisted dict should be updated - assert set(authz_map.compact_dict["users"]["test_agent"]["protected_rpcs"]) == {"method_1", "method_3"} + assert set(authz_map.compact_dict["users"]["test_agent"]["protected_rpcs"]) == { + "method_1", "method_3" + } # user_capabilities used in memory should be updated - assert set(authz_map.user_capabilities["test_agent"]["protected_rpcs"]) == {"method_1", "method_3"} + assert set( + authz_map.user_capabilities["test_agent"]["protected_rpcs"]) == {"method_1", "method_3"} # #5. update protected_topics, comments authz_map.create_or_merge_user_authz(identity="test_agent", protected_rpcs={"method_4"}, - comments="new comments" - ) + comments="new comments") # persisted dict should be updated - assert set(authz_map.compact_dict["users"]["test_agent"]["protected_rpcs"]) == {"method_1", "method_3", "method_4"} + assert set(authz_map.compact_dict["users"]["test_agent"]["protected_rpcs"]) == { + "method_1", "method_3", "method_4" + } # user_capabilities used in memory should be updated - assert set(authz_map.user_capabilities["test_agent"]["protected_rpcs"]) == {"method_1", "method_3", "method_4"} + assert set(authz_map.user_capabilities["test_agent"]["protected_rpcs"]) == { + "method_1", "method_3", "method_4" + } # assert str values assert (authz_map.compact_dict["users"]["test_agent"]["comments"] == @@ -512,53 +692,59 @@ def test_update_user(): # #6. update existing rpc_capability authz_map.create_or_merge_user_authz(identity="test_agent", - rpc_capabilities=authz.RPCCapabilities([ - authz.RPCCapability(resource="agent2.rpc2")])) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability(resource="agent2.rpc2")])) # persisted dict should be updated rpcs = authz_map.compact_dict["users"]["test_agent"].pop("protected_rpcs") assert set(rpcs) == {"method_1", "method_3", "method_4"} - assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "new comments", - "roles": ["test_role2"], - "rpc_capabilities": ["agent2.rpc2"], - "pubsub_capabilities": {"mytopic/*": "subscribe"}} + assert authz_map.compact_dict["users"]["test_agent"] == { + "comments": "new comments", + "roles": ["test_role2"], + "rpc_capabilities": ["agent2.rpc2"], + "pubsub_capabilities": { + "mytopic/*": "subscribe" + } + } # user_capabilities used in memory should be updated rpcs = authz_map.user_capabilities["test_agent"].pop("protected_rpcs") assert set(rpcs) == {"method_1", "method_3", "method_4"} - assert authz_map.user_capabilities["test_agent"] == {"comments": "new comments", - "roles": ["test_role2", "test_role"], - "rpc_capabilities": [ - "agent2.rpc2", - "id3.rpc3", - "id.rpc1"], - "pubsub_capabilities": {"mytopic/*": "subscribe"} - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "new comments", + "roles": ["test_role2", "test_role"], + "rpc_capabilities": ["agent2.rpc2", "id3.rpc3", "id.rpc1"], + "pubsub_capabilities": { + "mytopic/*": "subscribe" + } + } # #7. update users existing pubsub_capability authz_map.create_or_merge_user_authz(identity="test_agent", pubsub_capabilities=authz.PubsubCapabilities([ authz.PubsubCapability(topic_pattern="mytopic/*", topic_access="pubsub") - ]) - ) + ])) # persisted dict should be updated - assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "new comments", - "roles": ["test_role2"], - "rpc_capabilities": ["agent2.rpc2"], - "pubsub_capabilities": {"mytopic/*": "pubsub"} - } + assert authz_map.compact_dict["users"]["test_agent"] == { + "comments": "new comments", + "roles": ["test_role2"], + "rpc_capabilities": ["agent2.rpc2"], + "pubsub_capabilities": { + "mytopic/*": "pubsub" + } + } # user_capabilities used in memory should be updated - assert authz_map.user_capabilities["test_agent"] == {"comments": "new comments", - "roles": ["test_role2", "test_role"], - "rpc_capabilities": [ - "agent2.rpc2", - "id3.rpc3", - "id.rpc1"], - "pubsub_capabilities": {"mytopic/*": "pubsub"} - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "new comments", + "roles": ["test_role2", "test_role"], + "rpc_capabilities": ["agent2.rpc2", "id3.rpc3", "id.rpc1"], + "pubsub_capabilities": { + "mytopic/*": "pubsub" + } + } def test_add_users_to_group(): @@ -571,28 +757,36 @@ def test_add_users_to_group(): authz_map.create_or_merge_user_authz(identity="test_agent", comments="Created as part of test") assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} - authz_map.create_or_merge_user_authz(identity="test_agent2", comments="Created as part of test") + authz_map.create_or_merge_user_authz(identity="test_agent2", + comments="Created as part of test") assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # #2. create role authz_map.create_or_merge_role(name="test_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) # #3. create user group with users and role - authz_map.create_or_merge_user_group(name="group1", identities=["test_agent"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")])) + authz_map.create_or_merge_user_group(name="group1", + identities=["test_agent"], + roles=authz.UserRoles( + [authz.UserRole(role_name="test_role")])) # ####Now test - authz_map.add_users_to_group("group1", {"test_agent2", }) + authz_map.add_users_to_group("group1", { + "test_agent2", + }) - assert set(authz_map.compact_dict["user_groups"]["group1"]["identities"]) == {"test_agent2", "test_agent"} + assert set(authz_map.compact_dict["user_groups"]["group1"]["identities"]) == { + "test_agent2", "test_agent" + } assert authz_map.compact_dict["user_groups"]["group1"]["roles"] == ["test_role"] - assert authz_map.user_capabilities["test_agent2"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1"] - } + assert authz_map.user_capabilities["test_agent2"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1"] + } def test_remove_users_from_group(): @@ -605,36 +799,47 @@ def test_remove_users_from_group(): authz_map.create_or_merge_user_authz(identity="test_agent", comments="Created as part of test") assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} - authz_map.create_or_merge_user_authz(identity="test_agent2", comments="Created as part of test") + authz_map.create_or_merge_user_authz(identity="test_agent2", + comments="Created as part of test") assert authz_map.compact_dict["users"]["test_agent"] == {"comments": "Created as part of test"} # #2. create role authz_map.create_or_merge_role(name="test_role", - rpc_capabilities=authz.RPCCapabilities([authz.RPCCapability("id.rpc1")]) - ) + rpc_capabilities=authz.RPCCapabilities( + [authz.RPCCapability("id.rpc1")])) # #3. create user group with users and role - authz_map.create_or_merge_user_group(name="group1", identities=["test_agent", "test_agent2"], - roles=authz.UserRoles([authz.UserRole(role_name="test_role")])) - - assert set(authz_map.compact_dict["user_groups"]["group1"]["identities"]) == {"test_agent2", "test_agent"} + authz_map.create_or_merge_user_group(name="group1", + identities=["test_agent", "test_agent2"], + roles=authz.UserRoles( + [authz.UserRole(role_name="test_role")])) + + assert set(authz_map.compact_dict["user_groups"]["group1"]["identities"]) == { + "test_agent2", "test_agent" + } assert authz_map.compact_dict["user_groups"]["group1"]["roles"] == ["test_role"] - assert (authz_map.user_capabilities["test_agent2"] == authz_map.user_capabilities["test_agent"] == - {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1"] - }) + assert (authz_map.user_capabilities["test_agent2"] == authz_map.user_capabilities["test_agent"] + == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1"] + }) # ####Now test - authz_map.remove_users_from_group("group1", {"test_agent2", }) + authz_map.remove_users_from_group("group1", { + "test_agent2", + }) - assert set(authz_map.compact_dict["user_groups"]["group1"]["identities"]) == {"test_agent", } + assert set(authz_map.compact_dict["user_groups"]["group1"]["identities"]) == { + "test_agent", + } assert authz_map.compact_dict["user_groups"]["group1"]["roles"] == ["test_role"] assert authz_map.user_capabilities["test_agent2"] == {"comments": "Created as part of test"} - assert authz_map.user_capabilities["test_agent"] == {"comments": "Created as part of test", - "roles": ["test_role"], - "rpc_capabilities": ["id.rpc1"] - } + assert authz_map.user_capabilities["test_agent"] == { + "comments": "Created as part of test", + "roles": ["test_role"], + "rpc_capabilities": ["id.rpc1"] + } diff --git a/tests/unit/test_subsystems.py b/tests/unit/test_subsystems.py deleted file mode 100644 index f232f387f..000000000 --- a/tests/unit/test_subsystems.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- {{{ -# ===----------------------------------------------------------------------=== -# -# Installable Component of Eclipse VOLTTRON -# -# ===----------------------------------------------------------------------=== -# -# Copyright 2022 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. -# -# ===----------------------------------------------------------------------=== -# }}} - -from volttron.client import Agent - - -def test_subsystems_available(): - agent = Agent(enable_channel=True) - assert agent.vip.auth - assert agent.vip.channel - assert agent.vip.config - assert agent.vip.health - assert agent.vip.heartbeat - assert agent.vip.hello - assert agent.vip.peerlist - assert agent.vip.ping - assert agent.vip.pubsub - assert agent.vip.rpc - - # TODO: Add tests for enable/disable options. - - # agent = Agent(enable_store=False) - - # with pytest.raises(AttributeError): - # agent.vip.channel - # with pytest.raises(NameError): - # getattr(agent.vip, "web") - - # with pytest.raises(AttributeError): - # assert not agent.vip.config - - # assert agent.vip.auth - # assert agent.vip.health - # assert agent.vip.heartbeat - # assert agent.vip.hello - # assert agent.vip.peerlist - # assert agent.vip.ping - # assert agent.vip.pubsub - # assert agent.vip.rpc diff --git a/tests/unit/utils/test_environment_vars.py b/tests/unit/utils/test_environment_vars.py deleted file mode 100644 index dbddfade5..000000000 --- a/tests/unit/utils/test_environment_vars.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- {{{ -# ===----------------------------------------------------------------------=== -# -# Installable Component of Eclipse VOLTTRON -# -# ===----------------------------------------------------------------------=== -# -# Copyright 2022 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. -# -# ===----------------------------------------------------------------------=== -# }}} - -import os - -import mock -import pytest - -from volttron.utils import vip_main - - -class AgentMockery: - myargs = None - mykwargs = None - - def __init__(self, *args, **kwargs): - AgentMockery.myargs = args - AgentMockery.mykwargs = kwargs - - def run(self): - pass - - -def test_env_args_passed_to_agent(): - env = dict(AGENT_PUBLICKEY="uSo_q3vw-DpcOeCOXc1A4o1U11qpTtkkW2EviHM7x24", - AGENT_SECRETKEY="WpnCmf1vM1Z5gw0uIg8tr2C4erNQpSa0KONq9NvjzUE", - VOLTTRON_SERVERKEY="UH4tX5RDNTMjp5VPxVuj-M5QiO82BLUghYeWJ_CgvQc") - with mock.patch.dict(os.environ, env): - vip_main(AgentMockery, identity="foo") - assert env["AGENT_PUBLICKEY"] == AgentMockery.mykwargs['publickey'] - assert env["AGENT_SECRETKEY"] == AgentMockery.mykwargs['secretkey'] - assert env["VOLTTRON_SERVERKEY"] == AgentMockery.mykwargs['serverkey'] - - -def test_env_only_publickey_passed_to_agent(): - env = dict(AGENT_PUBLICKEY="uSo_q3vw-DpcOeCOXc1A4o1U11qpTtkkW2EviHM7x24") - with mock.patch.dict(os.environ, env): - with pytest.raises(ValueError): - vip_main(AgentMockery, identity="foo") diff --git a/tests/unit/utils/test_keystore.py b/tests/unit/utils/test_keystore.py deleted file mode 100644 index 4077e3d7e..000000000 --- a/tests/unit/utils/test_keystore.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- {{{ -# ===----------------------------------------------------------------------=== -# -# Installable Component of Eclipse VOLTTRON -# -# ===----------------------------------------------------------------------=== -# -# Copyright 2022 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. -# -# ===----------------------------------------------------------------------=== -# }}} - -import os - -import pytest - -from volttron.utils import keystore -from volttron.utils import jsonapi - -host_pair1 = {"addr": "tcp://127.0.0.1:1234", "key": "ABCDEFG"} -host_pair2 = {"addr": "tcp://192.168.0.2:1234", "key": "123456789"} - - -@pytest.fixture(scope="function") -def keystore_instance1(tmpdir_factory): - path = str(tmpdir_factory.mktemp("keys").join("keys.json")) - print("KEYSTORE PATH:", path) - keys = keystore.KeyStore(path) - keys.generate() - return keys - - -@pytest.mark.keystore -def test_keystore_generated_when_created(tmpdir_factory): - kspath = str(tmpdir_factory.mktemp("keys").join("keys.json")) - ks = keystore.KeyStore(kspath) - assert os.stat(kspath).st_mode & 0o777 == 0o600 - assert ks.secret - assert ks.public - - -@pytest.mark.keystore -def test_generated_keys_length(keystore_instance1): - """The keys should be the len:gth of an encoded curve-key (43)""" - assert len(keystore_instance1.public) == 43 - assert len(keystore_instance1.secret) == 43 - - -@pytest.mark.keystore -def test_keystore_with_same_path(keystore_instance1): - """Reading from the same path should fetch the same keys""" - path = keystore_instance1.filename - keys = keystore.KeyStore(path) - assert keystore_instance1.public == keys.public - assert keystore_instance1.secret == keys.secret - - -@pytest.mark.keystore -def test_keystore_overwrite_keys(keystore_instance1): - public = keystore_instance1.public - secret = keystore_instance1.secret - keystore_instance1.generate() - assert keystore_instance1.public != public - assert keystore_instance1.secret != secret - - -@pytest.fixture(scope="module") -def known_hosts_instance1(tmpdir_factory): - path = str(tmpdir_factory.mktemp("known_hosts").join("hosts.json")) - print("KNOWN HOSTS PATH:", path) - store = keystore.KnownHostsStore(path) - store.add(host_pair1["addr"], host_pair1["key"]) - store.add(host_pair2["addr"], host_pair2["key"]) - return store - - -@pytest.mark.keystore -def test_known_hosts_fetch(known_hosts_instance1): - """We should get what we put it""" - host = known_hosts_instance1 - assert host.serverkey(host_pair1["addr"]) == host_pair1["key"] - assert host.serverkey(host_pair2["addr"]) == host_pair2["key"] - - -@pytest.mark.keystore -def test_known_hosts_with_same_path(known_hosts_instance1): - """Reading from the same path should fetch the same keys""" - key1 = known_hosts_instance1.serverkey(host_pair1["addr"]) - key2 = known_hosts_instance1.serverkey(host_pair2["addr"]) - - host = keystore.KnownHostsStore(known_hosts_instance1.filename) - assert host.serverkey(host_pair1["addr"]) == key1 - assert host.serverkey(host_pair2["addr"]) == key2 - - -@pytest.mark.keystore -def test_known_hosts_update_entry(known_hosts_instance1): - new_key = "hijklmnop" - old_key = known_hosts_instance1.serverkey(host_pair1["addr"]) - assert new_key != old_key - - known_hosts_instance1.add(host_pair1["addr"], new_key) - assert known_hosts_instance1.serverkey(host_pair1["addr"]) == new_key - - -@pytest.mark.keystore -def test_invalid_unicode_key(keystore_instance1): - """ - Bypass KeyStore API and directly edit key to make it unicode. - The keys should always be ASCII characters. This is a precaution - against a corrupted key store. - """ - with open(keystore_instance1.filename) as fp: - keystore_json = jsonapi.load(fp) - keystore_json["public"] = "\u0100" - keystore_instance1.update(keystore_json) - assert keystore_instance1.public is None diff --git a/tests/unit/utils/test_load_utils.py b/tests/unit/utils/test_load_utils.py index b6d45c430..f5af876d6 100644 --- a/tests/unit/utils/test_load_utils.py +++ b/tests/unit/utils/test_load_utils.py @@ -26,12 +26,12 @@ from volttron.utils import load_config -def test_load_config_json(): - with pytest.raises(ValueError): - load_config(None) +def test_load_config_none(): + response = load_config(None) + assert {} == response -def test_raise_exception_no_file(): +def test_load_config_empty_string(): - with pytest.raises(ValueError): - load_config("") + response = load_config(None) + assert {} == response