def both_with_vc_vcp(request): """ Adds the volttron-central-address and volttron-central-serverkey to the main instance configuration file before starting the platform """ p = PlatformWrapper() if request.param[1] == 'local': start_wrapper_platform(p, with_http=True, add_local_vc_address=True) else: start_wrapper_platform(p, with_http=True) if request.param[0] == 'vcp-first': vcp_uuid = add_volttron_central_platform(p) vc_uuid = add_volttron_central(p) else: vc_uuid = add_volttron_central(p) vcp_uuid = add_volttron_central_platform(p) # Give the agents a chance to do stuff. note might take up to 10 sec # if the vcp is started first. gevent.sleep(10) yield p p.shutdown_platform()
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()
def vc_vcp_platforms(request): vc = PlatformWrapper() vcp = PlatformWrapper() # VC is setup to allow all connections vc.allow_all_connections() start_wrapper_platform(vc, with_http=True) if request.param == 'use-http': start_wrapper_platform(vcp, volttron_central_address=vc.bind_web_address) else: start_wrapper_platform(vcp, volttron_central_address=vc.vip_address, volttron_central_serverkey=vc.serverkey) vcp_uuid = add_volttron_central_platform(vcp) vc_uuid = add_volttron_central(vc) # Give the agents a chance to do stuff. Can take up to 10 seconds to # reconnect with vc. gevent.sleep(10) yield vc, vcp vc.shutdown_platform() vcp.shutdown_platform()
def vc_vcp_platforms(): """ This method returns two distinct platforms one vc and one vcp. When they are returned they should be registered together. This method will yield the two platforms as a tuple and then after the module is finished executing the cleanup of both will happen. """ vc = PlatformWrapper() vcp = PlatformWrapper() # VC is setup to allow all connections vc.allow_all_connections() start_wrapper_platform(vc, with_http=True) start_wrapper_platform(vcp, volttron_central_address=vc.vip_address, volttron_central_serverkey=vc.serverkey) vc_uuid = add_volttron_central(vc) vcp_uuid = add_volttron_central_platform(vcp) # Sleep so we know we are registered gevent.sleep(15) yield vc, vcp vc.shutdown_platform() vcp.shutdown_platform()
def instance(request): instance = PlatformWrapper(messagebus='rmq', ssl_auth=True) yield instance if instance.is_running(): instance.shutdown_platform() # In case platform was just killed stop_rabbit(rmq_home=instance.rabbitmq_config_obj.rmq_home, env=instance.env, quite=True)
def test_can_cleanup_installed_listener(): try: import psutil except: warnings.warn('No psutil module present for this test') return wrapper = PlatformWrapper() address="tcp://127.0.0.1:{}".format(get_rand_port()) wrapper.startup_platform(address) assert wrapper is not None assert wrapper.is_running() auuid = wrapper.install_agent(agent_dir=get_examples("ListenerAgent"), vip_identity="listener", start=False) assert auuid is not None started = wrapper.start_agent(auuid) assert isinstance(started, int) assert psutil.pid_exists(started) wrapper.shutdown_platform() # give operating system enough time to update pids. gevent.sleep(0.1) assert not psutil.pid_exists(started)
def get_n_volttron_instances(n, should_start=True, address_file=True): get_n_volttron_instances.count = n instances = [] vip_addresses = [] web_addresses = [] instances = [] addr_config = dict() names = [] for i in range(0, n): address = get_rand_vip() web_address = "http://{}".format(get_rand_ip_and_port()) vip_addresses.append(address) web_addresses.append(web_address) nm = 'platform{}'.format(i + 1) names.append(nm) for i in range(0, n): address = vip_addresses[i] web_address = web_addresses[i] wrapper = PlatformWrapper() addr_file = os.path.join(wrapper.volttron_home, 'external_address.json') if address_file: with open(addr_file, 'w') as f: json.dump(web_addresses, f) gevent.sleep(.1) wrapper.startup_platform(address, bind_web_address=web_address, instance_name=names[i], setupmode=True) wrapper.skip_cleanup = True instances.append(wrapper) gevent.sleep(11) for i in range(0, n): instances[i].shutdown_platform() gevent.sleep(1) # del instances[:] for i in range(0, n): address = vip_addresses.pop(0) web_address = web_addresses.pop(0) print address, web_address instances[i].startup_platform(address, bind_web_address=web_address, instance_name=names[i]) instances[i].allow_all_connections() gevent.sleep(11) instances = instances if n > 1 else instances[0] get_n_volttron_instances.instances = instances return instances
def build_n_volttron_instances(n, bad_config=False, add_my_address=True): build_n_volttron_instances.count = n instances = [] vip_addresses = [] instances = [] addr_config = dict() names = [] for i in range(0, n): address = get_rand_vip() vip_addresses.append(address) nm = 'platform{}'.format(i + 1) names.append(nm) for i in range(0, n): address = vip_addresses[i] wrapper = PlatformWrapper() wrapper.startup_platform(address, instance_name=names[i]) wrapper.skip_cleanup = True instances.append(wrapper) gevent.sleep(1) for i in range(0, n): instances[i].shutdown_platform() for i in range(0, n): addr_config.clear() for j in range(0, n): if j != i or (j == i and add_my_address): name = names[j] addr_config[name] = dict() addr_config[name]['instance-name'] = names[j] if bad_config: addr_config[name]['vip-address123'] = vip_addresses[j] else: addr_config[name]['vip-address'] = vip_addresses[j] addr_config[name]['serverkey'] = instances[j].serverkey address_file = os.path.join(instances[i].volttron_home, 'external_platform_discovery.json') if address_file: with open(address_file, 'w') as f: json.dump(addr_config, f) gevent.sleep(1) for i in range(0, n): address = vip_addresses.pop(0) instances[i].startup_platform(address, instance_name=names[i]) instances[i].allow_all_connections() gevent.sleep(11) instances = instances if n > 1 else instances[0] build_n_volttron_instances.instances = instances return instances
def test_can_cleanup_installed_listener(): try: import psutil except: warnings.warn('No psutil module present for this test') return wrapper = PlatformWrapper() address="tcp://127.0.0.1:{}".format(get_rand_port()) wrapper.startup_platform(address) assert wrapper is not None assert wrapper.is_running() auuid = wrapper.install_agent(agent_dir="examples/ListenerAgent", start=False) assert auuid is not None started = wrapper.start_agent(auuid) assert isinstance(started, int) assert psutil.pid_exists(started) wrapper.shutdown_platform() # give operating system enough time to update pids. gevent.sleep(0.1) assert not psutil.pid_exists(started)
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()
def build_wrapper(vip_address, should_start=True, messagebus='zmq', remote_platform_ca=None, instance_name=None, **kwargs): wrapper = PlatformWrapper(ssl_auth=kwargs.pop('ssl_auth', False), messagebus=messagebus, instance_name=instance_name, remote_platform_ca=remote_platform_ca) if should_start: wrapper.startup_platform(vip_address=vip_address, **kwargs) return wrapper
def build_wrapper(vip_address: str, should_start: bool = True, messagebus: str = 'zmq', remote_platform_ca: Optional[str] = None, instance_name: Optional[str] = None, secure_agent_users: bool = False, **kwargs): wrapper = PlatformWrapper(ssl_auth=kwargs.pop('ssl_auth', False), messagebus=messagebus, instance_name=instance_name, secure_agent_users=secure_agent_users, remote_platform_ca=remote_platform_ca) if should_start: wrapper.startup_platform(vip_address=vip_address, **kwargs) return wrapper
def test_can_create(messagebus, ssl_auth): p = PlatformWrapper(messagebus=messagebus, ssl_auth=ssl_auth) try: assert not p.is_running() assert p.volttron_home.startswith("/tmp/tmp") p.startup_platform(vip_address=get_rand_tcp_address()) assert p.is_running() finally: if p: p.shutdown_platform() assert not p.is_running()
def setup_instances(request): inst1 = PlatformWrapper() inst2 = PlatformWrapper() start_wrapper_platform(inst1) start_wrapper_platform(inst2) yield inst1, inst2 inst1.shutdown_platform() inst2.shutdown_platform()
def test_can_create_web_enabled(messagebus: str, https_enabled: bool): p = PlatformWrapper(messagebus=messagebus) try: assert not p.is_running() assert p.volttron_home.startswith("/tmp/tmp") http_address = get_rand_http_address(https=https_enabled) p.startup_platform(vip_address=get_rand_tcp_address(), bind_web_address=http_address) assert p.is_running() response = requests.get(http_address, verify=False) assert response.ok finally: if p: p.shutdown_platform() assert not p.is_running()
def build_agent(platform: PlatformWrapper, identity=None): """Builds an agent instance with the passed platform as its bus. The agent identity will be set. If the identity is set to None then a random identity will be created. """ os.environ['VOLTTRON_HOME'] = platform.volttron_home agent = platform.build_agent(identity) gevent.sleep(0.1) # switch context for a bit os.environ.pop('VOLTTRON_HOME') return agent
def test_channel_send_file(volttron_instance: PlatformWrapper): if not volttron_instance.messagebus == "zmq": pytest.skip("Channel only available for zmq message bus") return # Create with tarfile.open("/tmp/tmptar.tar", mode="w") as tf: for x in range(1, 50): with open(f"/tmp/data{x}", "w") as fin: fin.write("x" * 50) tf.add(f"/tmp/data{x}") os.remove(f"/tmp/data{x}") sender = volttron_instance.build_agent(agent_class=ChannelSender, identity="sender_agent", enable_channel=True) receiver = volttron_instance.build_agent(agent_class=ChannelReceiver, identity="receiver_agent", enable_channel=True) if os.path.exists(receiver.receiver_file_path): os.remove(receiver.receiver_file_path) sender.send_file(receiver.core.identity, "/tmp/tmptar.tar") assert os.path.isfile( receiver.receiver_file_path ), f"Couldn't find file {receiver.receiver_file_path}" assert hashlib.sha256(open("/tmp/tmptar.tar", 'rb').read()).hexdigest() == hashlib.sha256( open(receiver.receiver_file_path, 'rb').read()).hexdigest() sender.core.stop() receiver.core.stop()
def setup_platform(request): """ Creates a single instance of VOLTTRON with a VOLTTRON Central Platform, a listener agent, and a sqlite historian that is a platform.historian. The VOLTTRON Central Platform agent is not registered with a VOLTTRON Central Platform. """ vcp = PlatformWrapper(messagebus=request.param[0], ssl_auth=request.param[1]) start_wrapper_platform(vcp, with_http=True, add_local_vc_address=True) assert vcp assert vcp.is_running() vcp_uuid = add_volttron_central_platform(vcp) print("VCP uuid: {}".format(vcp_uuid)) # historian_config = SQLITE_HISTORIAN_CONFIG.copy() # historian_config['connection']['params']['database'] = \ # vcp.volttron_home + "/data/platform.historian.sqlite" # # historian_uuid = add_sqlhistorian(vcp, config=historian_config, # vip_identity='platform.historian') # listeneer_uuid = add_listener(vcp, vip_identity="platform.listener") assert vcp_uuid, "Invalid vcp uuid returned" assert vcp.is_agent_running(vcp_uuid), "vcp wasn't running!" # assert historian_uuid, "Invalid historian uuid returned" # assert vcp.is_agent_running(historian_uuid), "historian wasn't running!" # # assert listeneer_uuid, "Invalid listener uuid returned" # assert vcp.is_agent_running(listeneer_uuid), "listener wasn't running!" yield vcp print('Shutting down instance: {}'.format(vcp.volttron_home)) if vcp.is_running(): vcp.remove_all_agents() # Shutdown handles case where the platform hasn't started. vcp.shutdown_platform()
def test_channel_send_data(volttron_instance: PlatformWrapper): if not volttron_instance.messagebus == "zmq": pytest.skip("Channel only available for zmq message bus") return data = "x" * 50 sender = volttron_instance.build_agent(agent_class=ChannelSender, identity="sender_agent", enable_channel=True) receiver = volttron_instance.build_agent(agent_class=ChannelReceiver, identity="receiver_agent", enable_channel=True) sender.do_send(peer=receiver.core.identity, data=data.encode('utf-8'), channel_name="foo_data") assert sender.responses assert receiver.the_data assert receiver.the_data == data.encode('utf-8') sender.core.stop() receiver.core.stop()
def get_n_volttron_instances(n, should_start=True): get_n_volttron_instances.count = n instances = [] for i in range(0, n): address = get_rand_vip() wrapper = None if should_start: wrapper = build_wrapper(address) else: wrapper = PlatformWrapper() instances.append(wrapper) instances = instances if n > 1 else instances[0] # setattr(get_n_volttron_instances, 'instances', instances) get_n_volttron_instances.instances = instances return instances
def setup_instances(): inst1 = PlatformWrapper() inst2 = PlatformWrapper() start_wrapper_platform(inst1) start_wrapper_platform(inst2) yield inst1, inst2 inst1.shutdown_platform() inst2.shutdown_platform()
def test_encryption(): addr = 'tcp://127.0.0.1:55055' pub, sec = curve_keypair() publickey, secretkey = encode_key(pub), encode_key(sec) auth = {'allow': [{'credentials': 'CURVE:{}'.format(publickey)}]} plat = PlatformWrapper() plat.startup_platform(vip_address=addr, auth_dict=auth, encrypt=True) agent_addr = '{}?serverkey={}&publickey={}&secretkey=' \ '{}'.format(addr, plat.publickey, publickey, secretkey) agent1 = plat.build_agent(agent_addr, identity='agent1') peers = agent1.vip.peerlist.list().get(timeout=2) plat.shutdown_platform() print('PEERS: ', peers) assert len(peers) > 0
def build_agent_with_key(platform: PlatformWrapper, identity=None): """Create an agent instance that has a generated public and private key. The passed platform will be the vip-address of the agent and the identity will be set. If the identity is set to None then a random identity will be created. """ os.environ['VOLTTRON_HOME'] = platform.volttron_home keys = KeyStore(os.path.join(platform.volttron_home, identity + '.keys')) keys.generate() agent = platform.build_agent(identity=identity, serverkey=platform.publickey, publickey=keys.public, secretkey=keys.secret) # Make publickey easily accessible for these tests agent.publickey = keys.public gevent.sleep(0.1) # switch context for a bit os.environ.pop('VOLTTRON_HOME') return agent
def get_n_volttron_instances(n, should_start=True): print('GETTING NEW INSTANCES!!!!!', request.param, n) get_n_volttron_instances.count = n instances = [] for i in range(0, n): address = get_rand_vip() wrapper = None if should_start: if request.param == 'encrypted': print("building instance (using encryption)") wrapper = build_wrapper(address, encrypt=True) else: wrapper = build_wrapper(address) else: wrapper = PlatformWrapper() instances.append(wrapper) get_n_volttron_instances.param = request.param instances = instances if n > 1 else instances[0] get_n_volttron_instances.instances = instances return instances
def setup_platform(): """ Creates a single instance of VOLTTRON with a VOLTTRON Central Platform, a listener agent, and a sqlite historian that is a platform.historian. The VOLTTRON Central Platform agent is not registered with a VOLTTRON Central Platform. """ vcp = PlatformWrapper() start_wrapper_platform(vcp, with_http=True) assert vcp assert vcp.is_running() vcp_uuid = add_volttron_central_platform(vcp) historian_config = SQLITE_HISTORIAN_CONFIG.copy() historian_config['connection']['params']['database'] = \ vcp.volttron_home + "/data/platform.historian.sqlite" historian_uuid = add_sqlhistorian(vcp, config=historian_config, vip_identity='platform.historian') listeneer_uuid = add_listener(vcp, vip_identity="platform.listener") assert vcp_uuid, "Invalid vcp uuid returned" assert vcp.is_agent_running(vcp_uuid), "vcp wasn't running!" assert historian_uuid, "Invalid historian uuid returned" assert vcp.is_agent_running(historian_uuid), "historian wasn't running!" assert listeneer_uuid, "Invalid listener uuid returned" assert vcp.is_agent_running(listeneer_uuid), "listener wasn't running!" yield vcp vcp.shutdown_platform() vcp = None
def vcp_simulated_vc(request): """ This method yields a platform wrapper with a vcp installed and an agent connected to it with manager capabilities. The parameters are for each of the different identities we want to test with. """ p = PlatformWrapper() start_wrapper_platform(p, with_tcp=True) vcp_uuid = add_volttron_central_platform(p) # Build a connection to the just installed vcp agent. vc_simulated_agent = p.build_connection("platform.agent", identity="volttron.central") p.add_capabilities(vc_simulated_agent.server.core.publickey, "manager") yield p, vc_simulated_agent vc_simulated_agent.kill() p.shutdown_platform()
def build_wrapper(vip_address, **kwargs): wrapper = PlatformWrapper() print('BUILD_WRAPPER: {}'.format(vip_address)) wrapper.startup_platform(vip_address=vip_address, **kwargs) return wrapper
def test_pid_file(): try: import psutil except: warnings.warn('No psutil module present for this test') return wrapper = PlatformWrapper() address="tcp://127.0.0.1:{}".format(get_rand_port()) wrapper.startup_platform(address) assert wrapper is not None assert wrapper.is_running() pid_file = os.path.join(wrapper.volttron_home, "VOLTTRON_PID") assert os.path.exists(pid_file) with open(pid_file, 'r') as pf: assert psutil.pid_exists(int(pf.read().strip())) wrapper.skip_cleanup = True wrapper.shutdown_platform() # give operating system enough time to update pids. gevent.sleep(0.1) assert not os.path.exists(pid_file) # Check overwrite of pid file. In case last shutdown was not clean with open(pid_file, 'w') as pf: pf.write('abcd') wrapper = PlatformWrapper() address = "tcp://127.0.0.1:{}".format(get_rand_port()) wrapper.startup_platform(address) assert wrapper is not None assert wrapper.is_running() pid_file = os.path.join(wrapper.volttron_home, "VOLTTRON_PID") assert os.path.exists(pid_file) with open(pid_file, 'r') as pf: pid_str = pf.read().strip() assert psutil.pid_exists(int(pid_str)) # test start-volttron script we don't start a second volttron process if one # is already running env = os.environ.copy() env["VOLTTRON_HOME"] = wrapper.volttron_home vsource_home = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) process = Popen(["./start-volttron"], cwd=vsource_home, env=env, stderr=subprocess.PIPE, stdout=subprocess.PIPE) (output, error) = process.communicate() assert process.returncode == 1 assert "VOLTTRON with process id " + pid_str + " is already running" in \ output.decode("utf-8")