class TestSystemWSCommsServerOnly(unittest.TestCase): socket = 8881 def setUp(self): self.process = Process("proc", SyncFactory("sync")) Hello(self.process, dict(mri="hello")) self.process.add_comms( WebsocketServerComms(self.process, dict(port=self.socket))) self.process.start() def tearDown(self): self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:%s/ws" % self.socket) req = dict(type="malcolm:core/Post:1.0", id=0, endpoint=["hello", "greet"], parameters=dict(name="me")) conn.write_message(json.dumps(req)) resp = yield conn.read_message() resp = json.loads(resp) self.assertEqual( resp, dict(id=0, type="malcolm:core/Return:1.0", value=dict(greeting="Hello me"))) conn.close() def test_server_and_simple_client(self): self.send_message()
class TestSystemWSCommsServerAndClient(unittest.TestCase): socket = 8882 def setUp(self): sf = SyncFactory("sync") self.process = Process("proc", sf) Hello(self.process, dict(mri="hello")) Counter(self.process, dict(mri="counter")) self.process.add_comms( WebsocketServerComms(self.process, dict(port=self.socket))) self.process.start() # If we don't wait long enough, sometimes the websocket_connect() # in process2 will hang... time.sleep(0.1) self.process2 = Process("proc2", sf) self.process2.add_comms( WebsocketClientComms(self.process2, dict(hostname="localhost", port=self.socket))) self.process2.start() def tearDown(self): self.socket += 1 self.process.stop() self.process2.stop() def test_server_hello_with_malcolm_client(self): block2 = self.process2.make_client_block("hello") task = Task("task", self.process2) futures = task.when_matches_async(block2["state"], "Ready") task.wait_all(futures, timeout=1) ret = block2.greet("me2") self.assertEqual(ret, dict(greeting="Hello me2")) def test_server_counter_with_malcolm_client(self): block2 = self.process2.make_client_block("counter") task = Task("task", self.process2) futures = task.when_matches_async(block2["state"], "Ready") task.wait_all(futures, timeout=1) self.assertEqual(block2.counter, 0) block2.increment() self.assertEqual(block2.counter, 1)
class TestSystemWSCommsServerOnly(unittest.TestCase): socket = 8881 def setUp(self): self.process = Process("proc", SyncFactory("sync")) Hello(self.process, dict(mri="hello")) self.process.add_comms( WebsocketServerComms(self.process, dict(port=self.socket))) self.process.start() def tearDown(self): self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:%s/ws" % self.socket) req = dict( type="malcolm:core/Post:1.0", id=0, endpoint=["hello", "greet"], parameters=dict( name="me" ) ) conn.write_message(json.dumps(req)) resp = yield conn.read_message() resp = json.loads(resp) self.assertEqual(resp, dict( id=0, type="malcolm:core/Return:1.0", value=dict( greeting="Hello me" ) )) conn.close() def test_server_and_simple_client(self): self.send_message()
from malcolm.comms.websocket.websocketservercomms import WebsocketServerComms from malcolm.includes.pandabox.hardware_collection import hardware_collection # Input params HOSTNAME = "localhost" PORT = 8888 WSPORT = 8080 # Make the top level objects sf = SyncFactory("Sync") process = Process("Process", sf) # Add the websocket server params = WebsocketServerComms.MethodMeta.prepare_input_map(port=WSPORT) comms = WebsocketServerComms(process, params) process.add_comms(comms) # We daemonise the server by double forking, but we leave the controlling # terminal and other file connections alone. if False and os.fork(): # Exit first parent sys.exit(0) # Do second fork to avoid generating zombies if False and os.fork(): sys.exit(0) # Make the parts by querying the PandABox params = hardware_collection.MethodMeta.prepare_input_map(mriPrefix="P", hostname=HOSTNAME, port=PORT) _, parts = hardware_collection(process, params)
def make_process(): import sys import threading import argparse import logging from os import environ parser = argparse.ArgumentParser( description="Interactive shell for malcolm") parser.add_argument( '--client', '-c', help="Add a client to given server, like ws://localhost:8080 or pva") parser.add_argument( '--log', default="INFO", help="Lowest level of logs to see. One of: ERROR, WARNING, INFO, DEBUG " "Default is INFO") parser.add_argument( 'yaml', nargs="?", help="The YAML file containing the blocks to be loaded") args = parser.parse_args() # assuming loglevel is bound to the string value obtained from the # command line argument. Convert to upper case to allow the user to # specify --log=DEBUG or --log=debug numeric_level = getattr(logging, args.log.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % args.log) logging.basicConfig(level=numeric_level) from malcolm.core import SyncFactory, Process from malcolm.yamlutil import make_include_creator sf = SyncFactory("Sync") if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name, sf) with open(args.yaml) as f: assembly = make_include_creator(f.read()) params = assembly.MethodMeta.prepare_input_map() assembly(proc, params) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process", sf) proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.comms.websocket import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = WebsocketClientComms( proc, dict(hostname=hostname, port=int(port))) proc.add_comms(comms) else: raise ValueError("Don't know how to create client to %s" % args.client) def gui(block): global opener opener.open_gui(block, proc) try: environ['DISPLAY'] # If this environment variable doesn't exist then there is probably no # X server for us to talk to. except KeyError: pass else: from PyQt4.Qt import QApplication # Start qt def start_qt(): global app app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(False) from malcolm.gui.guiopener import GuiOpener global opener opener = GuiOpener() app.exec_() qt_thread = threading.Thread(target=start_qt) qt_thread.start() return proc, gui
from malcolm.comms.websocket.websocketservercomms import WebsocketServerComms from malcolm.includes.pandabox.hardware_collection import hardware_collection # Input params HOSTNAME = "localhost" PORT = 8888 WSPORT = 8080 # Make the top level objects sf = SyncFactory("Sync") process = Process("Process", sf) # Add the websocket server params = WebsocketServerComms.MethodMeta.prepare_input_map(port=WSPORT) comms = WebsocketServerComms(process, params) process.add_comms(comms) # We daemonise the server by double forking, but we leave the controlling # terminal and other file connections alone. if False and os.fork(): # Exit first parent sys.exit(0) # Do second fork to avoid generating zombies if False and os.fork(): sys.exit(0) # Make the parts by querying the PandABox params = hardware_collection.MethodMeta.prepare_input_map( mriPrefix="P", hostname=HOSTNAME, port=PORT) _, parts = hardware_collection(process, params)
def make_process(): import sys import threading import argparse import logging from os import environ parser = argparse.ArgumentParser( description="Interactive shell for malcolm") parser.add_argument( '--client', '-c', help="Add a client to given server, like ws://localhost:8080 or pva") parser.add_argument( '--log', default="INFO", help="Lowest level of logs to see. One of: ERROR, WARNING, INFO, DEBUG " "Default is INFO") parser.add_argument( 'yaml', nargs="?", help="The YAML file containing the blocks to be loaded" ) args = parser.parse_args() # assuming loglevel is bound to the string value obtained from the # command line argument. Convert to upper case to allow the user to # specify --log=DEBUG or --log=debug numeric_level = getattr(logging, args.log.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % args.log) logging.basicConfig(level=numeric_level) from malcolm.core import SyncFactory, Process from malcolm.yamlutil import make_include_creator try: environ['DISPLAY'] # If this environment variable doesn't exist then there is probably no # X server for us to talk to. except KeyError: pass else: from PyQt4.Qt import QApplication # Start qt def start_qt(): global app app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(False) from malcolm.gui.guiopener import GuiOpener global opener opener = GuiOpener() app.exec_() qt_thread = threading.Thread(target=start_qt) qt_thread.start() sf = SyncFactory("Sync") if args.yaml: proc_name = os.path.basename(args.yaml).split(".")[-2] proc = Process(proc_name, sf) with open(args.yaml) as f: assembly = make_include_creator(f.read()) assembly(proc, {}) proc_name = "%s - imalcolm" % proc_name else: proc = Process("Process", sf) proc_name = "imalcolm" # set terminal title sys.stdout.write("\x1b]0;%s\x07" % proc_name) if args.client: if args.client.startswith("ws://"): from malcolm.comms.websocket import WebsocketClientComms hostname, port = args.client[5:].split(":") comms = WebsocketClientComms( proc, dict(hostname=hostname, port=int(port))) proc.add_comms(comms) else: raise ValueError( "Don't know how to create client to %s" % args.client) def gui(block): global opener opener.open_gui(block, proc) return proc, gui