def test_will_update_throws_typeerror():
    # Note dictionary for os.environ must be string=string for key=value

    to_update = dict(shanty=dict(holy="cow"))
    #with pytest.raises(TypeError):
    with with_os_environ(to_update):
        print("Should not reach here")

    to_update = dict(bogus=35)
    #    with pytest.raises(TypeError):
    with with_os_environ(to_update):
        print("Should not reach here")
def test_delete_credential(volttron_instance_web):
    instance = volttron_instance_web
    auth_pending = instance.dynamic_agent.vip.rpc.call(
        AUTH, "get_authorization_pending").get()
    print(f"Auth pending is: {auth_pending}")
    len_auth_pending = len(auth_pending)
    with with_os_environ(instance.env):
        pending_agent = Agent(identity="PendingAgent3")
        task = gevent.spawn(pending_agent.core.run)
        task.join(timeout=5)
        pending_agent.core.stop()

        auth_pending = instance.dynamic_agent.vip.rpc.call(
            AUTH, "get_authorization_pending").get()
        print(f"Auth pending is: {auth_pending}")
        assert len(auth_pending) == len_auth_pending + 1

        instance.dynamic_agent.vip.rpc.call(
            AUTH, "delete_authorization_failure",
            auth_pending[0]["user_id"]).wait(timeout=4)
        gevent.sleep(2)
        auth_pending = instance.dynamic_agent.vip.rpc.call(
            AUTH, "get_authorization_pending").get()

        assert len(auth_pending) == len_auth_pending
Beispiel #3
0
def test_install_arg_matrix(volttron_instance: PlatformWrapper, args: List,
                            use_config: bool):
    listener_config_file = get_examples("ListenerAgent/config")

    with with_os_environ(volttron_instance.env):
        # Don't change the parametrized args that have mutable values. Make copy if changing within test.
        # parameterized args when used with more than 1 .parametrize() or with another parameterized fixture
        # fails to rest values correctly
        # @pytest.mark.parametrize("x,y", (([1, 2], 1), ([3, 4], 1))) - will work fine even if x is changed in test
        # But
        # @pytest.mark.parametrize("x,y", (([1,2],1), ([3,4],1)))
        # @pytest.mark.parametrize("z", [8, 9])
        # will fail to reset value of x correctly if x is changed within test

        vctl_args = copy.copy(args)
        vctl_args.insert(0, "--json")
        vctl_args.insert(0, "volttron-ctl")

        if use_config:
            vctl_args.extend(["--agent-config", listener_config_file])

        response = execute_command(vctl_args, volttron_instance.env)

        json_response = jsonapi.loads(response)

        agent_uuid = json_response["agent_uuid"]
        gevent.sleep(1)

        response = execute_command(["vctl", "--json", "status", agent_uuid],
                                   volttron_instance.env)
        json_response = jsonapi.loads(response)

        identity = list(json_response.keys())[0]
        agent_status_dict = json_response[identity]

        if "--start" in vctl_args:
            assert agent_status_dict["status"]

        if "--tag" in vctl_args:
            assert agent_status_dict["agent_tag"]
            tag_name = vctl_args[vctl_args.index("--tag") + 1]
            assert tag_name == agent_status_dict["agent_tag"]

        if "--vip-identity" in vctl_args:
            assert agent_status_dict["identity"]
            expected_identity = vctl_args[vctl_args.index("--vip-identity") +
                                          1]
            assert expected_identity == agent_status_dict["identity"]

        if use_config:
            with open(listener_config_file) as fp:
                expected_config = yaml.safe_load(fp.read())
            config_path = Path(volttron_instance.volttron_home).joinpath(
                f"agents/{agent_uuid}/listeneragent-3.3/listeneragent-3.3.dist-info/config"
            )
            with open(config_path) as fp:
                config_data = yaml.safe_load(fp.read())
                assert expected_config == config_data

        volttron_instance.remove_all_agents()
Beispiel #4
0
def test_agent_filters(volttron_instance):
    auuid = volttron_instance.install_agent(
        agent_dir=get_examples("ListenerAgent"), start=True)
    buuid = volttron_instance.install_agent(
        agent_dir=get_examples("ListenerAgent"), start=True)

    # Verify all installed agents show up in list
    with with_os_environ(volttron_instance.env):
        p = subprocess.Popen(
            ["volttron-ctl", "list"],
            env=volttron_instance.env,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True,
        )
        agent_list = p.communicate()
        assert "listeneragent-3.3_1" in str(agent_list)
        assert "listeneragent-3.3_2" in str(agent_list)

    # Filter agent based on agent uuid
    with with_os_environ(volttron_instance.env):
        p = subprocess.Popen(
            ["volttron-ctl", "list", str(auuid)],
            env=volttron_instance.env,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True,
        )
        agent_list = p.communicate()
        assert "listeneragent-3.3_1" in str(agent_list)
        assert "listeneragent-3.3_2" not in str(agent_list)

    # Filter agent based on agent name
    with with_os_environ(volttron_instance.env):
        p = subprocess.Popen(
            ["volttron-ctl", "list", "listeneragent-3.3_1"],
            env=volttron_instance.env,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True,
        )
        agent_list = p.communicate()
        assert "listeneragent-3.3_1" in str(agent_list)
        assert "listeneragent-3.3_2" not in str(agent_list)
Beispiel #5
0
def auth_add(platform, entry):
    with with_os_environ(platform.env):
        p = subprocess.Popen(['volttron-ctl', 'auth', 'add'],
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate(input=entry_to_input_string(**entry.__dict__))
        assert p.returncode == 0
Beispiel #6
0
def test_install_with_wheel_bad_path(volttron_instance: PlatformWrapper):

    with with_os_environ(volttron_instance.env):
        bad_wheel_path = "foo/wheel.whl"
        args = ["volttron-ctl", "--json", "install", bad_wheel_path]
        try:
            response = execute_command(args, volttron_instance.env)
        except RuntimeError as exc:
            assert f"Invalid file {bad_wheel_path}" in exc.args[0]
Beispiel #7
0
def auth_update(platform, index, **kwargs):
    with with_os_environ(platform.env):
        p = subprocess.Popen(['volttron-ctl', 'auth', 'update',
                              str(index)],
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate(input=entry_to_input_string(**kwargs))
        assert p.returncode == 0
Beispiel #8
0
def auth_remove(platform, index):
    with with_os_environ(platform.env):
        p = subprocess.Popen(['volttron-ctl', 'auth', 'remove',
                              str(index)],
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate(input='Y\n')
        assert p.returncode == 0
Beispiel #9
0
def _remove_group_or_role(platform, cmd, key):
    with with_os_environ(platform.env):
        args = ['volttron-ctl', 'auth', cmd, key]
        p = subprocess.Popen(args,
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate()
        assert p.returncode == 0
Beispiel #10
0
def _remove_known_host(platform, host):
    with with_os_environ(platform.env):
        args = ['volttron-ctl', 'auth', 'remove-known-host', host]
        p = subprocess.Popen(args,
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate()
        assert p.returncode == 0
Beispiel #11
0
def _add_group_or_role(platform, cmd, name, list_):
    with with_os_environ(platform.env):
        args = ['volttron-ctl', 'auth', cmd, name]
        args.extend(list_)
        p = subprocess.Popen(args,
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate()
        assert p.returncode == 0
Beispiel #12
0
def _add_known_host(platform, host, serverkey):
    with with_os_environ(platform.env):
        args = ['volttron-ctl', 'auth', 'add-known-host']
        args.extend(['--host', host])
        args.extend(['--serverkey', serverkey])
        p = subprocess.Popen(args,
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate()
        assert p.returncode == 0
Beispiel #13
0
def _update_group_or_role(platform, cmd, key, values, remove):
    with with_os_environ(platform.env):
        args = ['volttron-ctl', 'auth', cmd, key]
        args.extend(values)
        if remove:
            args.append('--remove')
        p = subprocess.Popen(args,
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate()
        assert p.returncode == 0
Beispiel #14
0
def auth_instance(volttron_instance):
    with open(os.path.join(volttron_instance.volttron_home, "auth.json"),
              'r') as f:
        auth_file = jsonapi.load(f)
    print(auth_file)
    try:
        yield volttron_instance
    finally:
        with with_os_environ(volttron_instance.env):
            with open(
                    os.path.join(volttron_instance.volttron_home, "auth.json"),
                    'w') as f:
                jsonapi.dump(auth_file, f)
Beispiel #15
0
def auth_rpc_method_remove(platform, agent, method, auth_cap):
    with with_os_environ(platform.env):
        with subprocess.Popen([
                'volttron-ctl', 'auth', 'rpc', 'remove', f'{agent}.{method}',
                auth_cap
        ],
                              env=platform.env,
                              stdin=subprocess.PIPE,
                              universal_newlines=True) as p:
            out, err = p.communicate()
            assert p.returncode == 0
    print(f"Out is: {out}")
    print(f"ERROR is: {err}")
Beispiel #16
0
def _list_known_hosts(platform):
    with with_os_environ(platform.env):
        output = subprocess.check_output(
            ['volttron-ctl', 'auth', 'list-known-hosts'],
            env=platform.env,
            universal_newlines=True)

        lines = output.split('\n')
        dict_ = {}
        for line in lines[2:-1]:  # skip two header lines and last (empty) line
            host, pubkey = ' '.join(
                line.split()).split()  # combine multiple spaces
            dict_[host] = pubkey
        return dict_
Beispiel #17
0
def test_install_with_wheel(volttron_instance: PlatformWrapper):

    with with_os_environ(volttron_instance.env):
        global listener_agent_dir
        args = ["volttron-pkg", "package", listener_agent_dir]
        response = execute_command(args, volttron_instance.env)
        assert response.startswith("Package created at: ")
        path = response[len("Package created at: "):]
        assert os.path.exists(path.strip())
        args = ["volttron-ctl", "--json", "install", path.strip()]
        response = execute_command(args, volttron_instance.env)
        response_dict = jsonapi.loads(response)
        assert response_dict.get("agent_uuid")
        volttron_instance.remove_all_agents()
Beispiel #18
0
def _list_groups_or_roles(platform, cmd):
    with with_os_environ(platform.env):
        output = subprocess.check_output(['volttron-ctl', 'auth', cmd],
                                         env=platform.env,
                                         universal_newlines=True)
        # For these tests don't use names that contain space, [, comma, or '
        output = output.replace('[', '').replace("'", '').replace(']', '')
        output = output.replace(',', '')
        lines = output.split('\n')

        dict_ = {}
        for line in lines[2:-1]:  # skip two header lines and last (empty) line
            list_ = ' '.join(line.split()).split()  # combine multiple spaces
            dict_[list_[0]] = list_[1:]
        return dict_
def test_get_credentials(volttron_instance_web):
    instance = volttron_instance_web
    auth_pending = instance.dynamic_agent.vip.rpc.call(
        AUTH, "get_authorization_pending").get()
    len_auth_pending = len(auth_pending)
    with with_os_environ(instance.env):
        pending_agent = Agent(identity="PendingAgent")
        task = gevent.spawn(pending_agent.core.run)
        task.join(timeout=5)
        pending_agent.core.stop()

    auth_pending = instance.dynamic_agent.vip.rpc.call(
        AUTH, "get_authorization_pending").get()
    print(f"Auth pending is: {auth_pending}")

    assert len(auth_pending) == len_auth_pending + 1
Beispiel #20
0
def auth_add_cmd_line(platform, entry):
    args = ['volttron-ctl', 'auth', 'add']
    fields = entry.__dict__.copy()
    enabled = fields.pop('enabled')
    for k, v in fields.items():
        if isinstance(v, list):
            v = ','.join(v)
        if v:
            if k == "capabilities":
                args.extend(['--' + k, f"{jsonapi.dumps(v)}"])
            else:
                args.extend(['--' + k, v])

    if not enabled:
        args.append('--disabled')

    with with_os_environ(platform.env):
        print(args)
        p = subprocess.Popen(args,
                             env=platform.env,
                             stdin=subprocess.PIPE,
                             universal_newlines=True)
        p.communicate()
        assert p.returncode == 0
def test_will_update_environ():
    to_update = dict(farthing="50")
    with with_os_environ(to_update):
        assert os.environ.get("farthing") == "50"

    assert "farthing" not in os.environ
def federated_rmq_instances(request, **kwargs):
    """
    Create two rmq based volttron instances. One to act as producer of data and one to act as consumer of data
    producer is upstream instance and consumer is the downstream instance

    :return: 2 volttron instances - (producer, consumer) that are federated
    """
    upstream_vip = get_rand_vip()
    upstream_hostname, upstream_https_port = get_hostname_and_random_port()
    web_address = 'https://{hostname}:{port}'.format(
        hostname=upstream_hostname, port=upstream_https_port)
    upstream = build_wrapper(upstream_vip,
                             ssl_auth=True,
                             messagebus='rmq',
                             should_start=True,
                             bind_web_address=web_address,
                             instance_name='volttron1',
                             **kwargs)
    upstream.enable_auto_csr()
    downstream_vip = get_rand_vip()
    hostname, https_port = get_hostname_and_random_port()
    downstream_web_address = 'https://{hostname}:{port}'.format(
        hostname=hostname, port=https_port)

    downstream = build_wrapper(downstream_vip,
                               ssl_auth=True,
                               messagebus='rmq',
                               should_start=False,
                               bind_web_address=downstream_web_address,
                               instance_name='volttron2',
                               **kwargs)

    link_name = None
    rmq_mgmt = None
    try:
        # create federation config and save in volttron home of 'downstream' instance
        content = dict()
        fed = dict()
        fed[upstream.rabbitmq_config_obj.rabbitmq_config["host"]] = {
            'port':
            upstream.rabbitmq_config_obj.rabbitmq_config["amqp-port-ssl"],
            'virtual-host':
            upstream.rabbitmq_config_obj.rabbitmq_config["virtual-host"],
            'https-port':
            upstream_https_port,
            'federation-user':
            "******".format(downstream.instance_name)
        }
        content['federation-upstream'] = fed
        import yaml
        config_path = os.path.join(downstream.volttron_home,
                                   "rabbitmq_federation_config.yml")
        with open(config_path, 'w') as yaml_file:
            yaml.dump(content, yaml_file, default_flow_style=False)

        # setup federation link from 'downstream' to 'upstream' instance
        downstream.setup_federation(config_path)

        downstream.startup_platform(vip_address=downstream_vip,
                                    bind_web_address=downstream_web_address)
        with with_os_environ(downstream.env):
            rmq_mgmt = RabbitMQMgmt()
            links = rmq_mgmt.get_federation_links()
            assert links and links[0]['status'] == 'running'
            link_name = links[0]['name']

    except Exception as e:
        print("Exception setting up federation: {}".format(e))
        upstream.shutdown_platform()
        if downstream.is_running():
            downstream.shutdown_platform()
        raise e

    yield upstream, downstream

    if link_name and rmq_mgmt:
        rmq_mgmt.delete_multiplatform_parameter('federation-upstream',
                                                link_name)
    upstream.shutdown_platform()
    downstream.shutdown_platform()
def two_way_federated_rmq_instances(request, **kwargs):
    """
    Create two rmq based volttron instances. Create bi-directional data flow channel
    by creating 2 federation links

    :return: 2 volttron instances - that are connected through federation
    """
    instance_1_vip = get_rand_vip()
    instance_1_hostname, instance_1_https_port = get_hostname_and_random_port()
    instance_1_web_address = 'https://{hostname}:{port}'.format(
        hostname=instance_1_hostname, port=instance_1_https_port)

    instance_1 = build_wrapper(instance_1_vip,
                               ssl_auth=True,
                               messagebus='rmq',
                               should_start=True,
                               bind_web_address=instance_1_web_address,
                               instance_name='volttron1',
                               **kwargs)

    instance_1.enable_auto_csr()

    instance_2_vip = get_rand_vip()
    instance_2_hostname, instance_2_https_port = get_hostname_and_random_port()
    instance_2_webaddress = 'https://{hostname}:{port}'.format(
        hostname=instance_2_hostname, port=instance_2_https_port)

    instance_2 = build_wrapper(instance_2_vip,
                               ssl_auth=True,
                               messagebus='rmq',
                               should_start=False,
                               bind_web_address=instance_2_webaddress,
                               instance_name='volttron2',
                               **kwargs)

    instance_2_link_name = None
    instance_1_link_name = None

    try:
        # create federation config and setup federation link to instance_1
        content = dict()
        fed = dict()
        fed[instance_1.rabbitmq_config_obj.rabbitmq_config["host"]] = {
            'port':
            instance_1.rabbitmq_config_obj.rabbitmq_config["amqp-port-ssl"],
            'virtual-host':
            instance_1.rabbitmq_config_obj.rabbitmq_config["virtual-host"],
            'https-port':
            instance_1_https_port,
            'federation-user':
            "******".format(instance_2.instance_name)
        }
        content['federation-upstream'] = fed
        import yaml
        config_path = os.path.join(instance_2.volttron_home,
                                   "rabbitmq_federation_config.yml")
        with open(config_path, 'w') as yaml_file:
            yaml.dump(content, yaml_file, default_flow_style=False)

        print(f"instance 2 Fed config path:{config_path}, content: {content}")

        instance_2.setup_federation(config_path)
        instance_2.startup_platform(vip_address=instance_2_vip,
                                    bind_web_address=instance_2_webaddress)
        instance_2.enable_auto_csr()
        # Check federation link status
        with with_os_environ(instance_2.env):
            rmq_mgmt = RabbitMQMgmt()
            links = rmq_mgmt.get_federation_links()
            print(f"instance 2 fed links state: {links[0]['status']}")
            assert links and links[0]['status'] == 'running'
            instance_2_link_name = links[0]['name']

        instance_1.skip_cleanup = True
        instance_1.shutdown_platform()
        instance_1.skip_cleanup = False

        start_rabbit(rmq_home=instance_1.rabbitmq_config_obj.rmq_home,
                     env=instance_1.env)

        # create federation config and setup federation to instance_2
        content = dict()
        fed = dict()
        fed[instance_2.rabbitmq_config_obj.rabbitmq_config["host"]] = {
            'port':
            instance_2.rabbitmq_config_obj.rabbitmq_config["amqp-port-ssl"],
            'virtual-host':
            instance_2.rabbitmq_config_obj.rabbitmq_config["virtual-host"],
            'https-port':
            instance_2_https_port,
            'federation-user':
            "******".format(instance_1.instance_name)
        }
        content['federation-upstream'] = fed
        import yaml
        config_path = os.path.join(instance_1.volttron_home,
                                   "rabbitmq_federation_config.yml")
        with open(config_path, 'w') as yaml_file:
            yaml.dump(content, yaml_file, default_flow_style=False)

        print(f"instance 1 Fed config path:{config_path}, content: {content}")

        instance_1.setup_federation(config_path)
        instance_1.startup_platform(vip_address=instance_1_vip,
                                    bind_web_address=instance_1_web_address)
        import gevent
        gevent.sleep(10)
        # Check federation link status
        with with_os_environ(instance_1.env):
            rmq_mgmt = RabbitMQMgmt()
            links = rmq_mgmt.get_federation_links()
            print(f"instance 1 fed links state: {links[0]['status']}")
            assert links and links[0]['status'] == 'running'
            instance_1_link_name = links[0]['name']

    except Exception as e:
        print(f"Exception setting up federation: {e}")
        instance_1.shutdown_platform()
        instance_2.shutdown_platform()
        raise e

    yield instance_1, instance_2

    if instance_1_link_name:
        with with_os_environ(instance_1.env):
            rmq_mgmt = RabbitMQMgmt()
            rmq_mgmt.delete_multiplatform_parameter('federation-upstream',
                                                    instance_1_link_name)
    if instance_2_link_name:
        with with_os_environ(instance_2.env):
            rmq_mgmt = RabbitMQMgmt()
            rmq_mgmt.delete_multiplatform_parameter('federation-upstream',
                                                    instance_2_link_name)
    instance_1.shutdown_platform()
    instance_2.shutdown_platform()
Beispiel #24
0
def auth_list(platform):
    with with_os_environ(platform.env):
        return subprocess.check_output(['volttron-ctl', 'auth', 'list'],
                                       env=platform.env,
                                       universal_newlines=True)
Beispiel #25
0
def test_install_same_identity(volttron_instance: PlatformWrapper):
    global listener_agent_dir
    with with_os_environ(volttron_instance.env):
        expected_identity = "listener.1"
        args = [
            "volttron-ctl",
            "--json",
            "install",
            listener_agent_dir,
            "--vip-identity",
            expected_identity,
            "--start",
        ]
        response = execute_command(args, volttron_instance.env)
        json_response = jsonapi.loads(response)
        agent_uuid = json_response["agent_uuid"]
        response = execute_command(["vctl", "--json", "status", agent_uuid],
                                   volttron_instance.env)
        json_response = jsonapi.loads(response)
        identity = list(json_response.keys())[0]
        agent_status_dict = json_response[identity]

        assert "running [" in agent_status_dict.get("status")

        expected_status = agent_status_dict.get("status")
        expected_auuid = agent_status_dict.get("agent_uuid")

        # Attempt to install without force.
        with pytest.raises(RuntimeError):
            execute_command(args, volttron_instance.env)

        # Nothing should have changed the pid should be the same
        response = execute_command(["vctl", "--json", "status", agent_uuid],
                                   volttron_instance.env)
        json_response = jsonapi.loads(response)
        identity = list(json_response.keys())[0]
        agent_status_dict = json_response[identity]
        assert expected_status == agent_status_dict.get("status")
        assert expected_auuid == agent_status_dict.get("agent_uuid")

        args = [
            "volttron-ctl",
            "--json",
            "install",
            listener_agent_dir,
            "--vip-identity",
            expected_identity,
            "--start",
            "--force",
        ]

        # Install with force.
        response = execute_command(args, volttron_instance.env)
        json_response = jsonapi.loads(response)
        agent_uuid = json_response["agent_uuid"]
        response = execute_command(["vctl", "--json", "status", agent_uuid],
                                   volttron_instance.env)
        json_response = jsonapi.loads(response)
        identity = list(json_response.keys())[0]
        agent_status_dict = json_response[identity]

        assert "running [" in agent_status_dict.get("status")
        assert expected_status != agent_status_dict.get("status")
        assert expected_auuid != agent_status_dict.get("agent_uuid")