def test_counter_subscribe(self): sync_factory = SyncFactory("sched") process = Process("proc", sync_factory) b = Counter(process, dict(mri="counting"))[0] process.start() # wait until block is Ready task = Task("counter_ready_task", process) task.when_matches(b["state"], "Ready", timeout=1) q = sync_factory.create_queue() sub = Subscribe(response_queue=q, context="ClientConnection", endpoint=["counting", "counter"], delta=False) process.q.put(sub) resp = q.get(timeout=1) self.assertIsInstance(resp, Update) attr = NTScalar.from_dict(resp.value) self.assertEqual(0, attr.value) post = Post(response_queue=q, context="ClientConnection", endpoint=["counting", "increment"]) process.q.put(post) resp = q.get(timeout=1) self.assertIsInstance(resp, Update) self.assertEqual(resp.value["value"], 1) resp = q.get(timeout=1) self.assertIsInstance(resp, Return) process.stop()
class TestSystemWSCommsServerAndClient(TestSystemWSCommsServerOnly): socket = 8882 def setUp(self): super(TestSystemWSCommsServerAndClient, self).setUp() self.process2 = Process("proc2", self.sf) self.block2 = Block() ClientController(self.process2, self.block2, 'hello') self.cc = WSClientComms("cc", self.process2, "ws://localhost:%s/ws" % self.socket) self.process2.start() self.cc.start() def tearDown(self): super(TestSystemWSCommsServerAndClient, self).tearDown() self.cc.stop() self.cc.wait() self.process2.stop() def test_server_with_malcolm_client(self): # Normally we would wait for it to be connected here, but it isn't # attached to a process so just sleep for a bit time.sleep(0.5) ret = self.block2.say_hello("me2") self.assertEqual(ret, dict(greeting="Hello me2"))
class TestSystemWSCommsServerOnly(unittest.TestCase): socket = 8881 def setUp(self): self.sf = SyncFactory("sync") self.process = Process("proc", self.sf) block = Block() HelloController(self.process, block, 'hello') self.sc = WSServerComms("sc", self.process, self.socket) self.process.start() self.sc.start() def tearDown(self): self.sc.stop() self.sc.wait() self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:%s/ws" % self.socket) req = dict(type="Post", id=0, endpoint=["hello", "say_hello"], 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="Return", value=dict(greeting="Hello me"))) conn.close() def test_server_and_simple_client(self): self.send_message()
def test_add_block_calls_handle(self): s = SyncFactory("sched") p = Process("proc", s) b = Block() b.set_parent(p, "myblock") p.add_block(b) p.start() p.stop() self.assertEqual(len(p._blocks), 2) self.assertEqual(p._blocks, dict(myblock=b, proc=p.process_block))
def test_error(self): s = SyncFactory("sched") p = Process("proc", s) p.log_exception = MagicMock() p.start() request = MagicMock() request.endpoint = ["anything"] p.q.put(request) p.stop() p.log_exception.assert_called_once_with("Exception while handling %s", request)
def test_add_block_calls_handle(self): s = SyncFactory("sched") p = Process("proc", s) b = Block() c = MagicMock() b.set_process_path(p, ("myblock",)) p.add_block(b, c) p.start() p.stop() self.assertEqual(len(p._blocks), 2) self.assertEqual(p._blocks, dict(myblock=b, proc=p.process_block))
def test_add_block_calls_handle(self): s = SyncFactory("sched") p = Process("proc", s) b = MagicMock() b.name = "myblock" p.add_block("myblock", b) p.start() p.stop() b.set_parent.assert_called_once_with(p, "myblock") self.assertEqual(len(p._blocks), 2) self.assertEqual(p._blocks, dict(myblock=b, proc=p.process_block))
def test_starting_process(self): s = SyncFactory("sched") p = Process("proc", s) b = MagicMock() p._handle_block_add(BlockAdd(b, "myblock", None)) self.assertEqual(p._blocks, dict(myblock=b, proc=ANY)) p.start() request = Post(MagicMock(), MagicMock(), ["myblock", "foo"]) p.q.put(request) # wait for spawns to have done their job p.stop() b.handle_request.assert_called_once_with(request)
class TestSystemWSComms(unittest.TestCase): def setUp(self): sync_factory = SyncFactory("sync") self.process = Process("proc", sync_factory) block = Block("hello") self.process.add_block(block) HelloController(block) self.sc = WSServerComms("sc", self.process, 8888) self.process.start() self.sc.start() def tearDown(self): self.sc.stop() self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:8888/ws") req = dict( type="Post", id=0, endpoint=["hello", "say_hello"], 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="Return", value=dict( greeting="Hello me" ) )) conn.close() def test_server_and_simple_client(self): self.send_message() def test_server_with_malcolm_client(self): self.cc = WSClientComms("cc", self.process, "ws://localhost:8888/ws") self.cc.start() # Wait for comms to be connected while not self.cc.conn.done(): time.sleep(0.001) # Don't add to process as we already have a block of that name block2 = Block("hello") ClientController(self.process, block2, self.cc) ret = block2.say_hello("me2") self.assertEqual(ret, dict(greeting="Hello me2")) self.cc.stop()
def test_spawned_adds_to_other_spawned(self): s = SyncFactory("sched") p = Process("proc", s) def sleep(n, a=None): time.sleep(a) f = MagicMock(side_effect=sleep) spawned = p.spawn(f, "fred", a=0.05) p.start() p.stop() self.assertEqual(p._other_spawned, [(spawned, f)]) f.assert_called_once_with("fred", a=0.05)
def test_starting_process(self): s = SyncFactory("sched") p = Process("proc", s) b = MagicMock() b.name = "myblock" p.add_block(b) self.assertEqual(p._blocks, dict(myblock=b)) p.start() request = MagicMock() request.endpoint = ["myblock", "foo"] p.q.put(request) # wait for spawns to have done their job p.stop() b.handle_request.assert_called_once_with(request)
class TestProcess(unittest.TestCase): def setUp(self): self.o = Process("proc") self.o.start() def tearDown(self): self.o.stop(timeout=1) def test_init(self): assert self.o.name == "proc" def test_add_controller(self): controller = MagicMock() self.o.add_controller("mri", controller) assert self.o.get_controller("mri") == controller def test_init_controller(self): class InitController(Controller): init = False @Process.Init def do_init(self): self.init = True c = InitController(self.o, "mri", []) self.o.add_controller("mri", c) assert c.init == True def test_publish_controller(self): class PublishController(Controller): published = [] @Process.Publish def do_publish(self, published): self.published = published c = PublishController(self.o, "mri", []) self.o.add_controller("mri", c) assert c.published == ["mri"] self.o.add_controller("mri2", MagicMock()) assert c.published == ["mri", "mri2"] self.o.add_controller("mri3", MagicMock(), False) assert c.published == ["mri", "mri2"] self.o.remove_controller("mri2") assert c.published == ["mri"]
def test_hello_controller_with_process(self): sync_factory = SyncFactory("sched") process = Process("proc", sync_factory) block = Block("hello") HelloController(block) process.add_block(block) process.start() q = sync_factory.create_queue() req = Request.Post(response_queue=q, context="ClientConnection", endpoint=["hello", "say_hello"], parameters=dict(name="thing")) req.set_id(44) process.q.put(req) resp = q.get(timeout=1) self.assertEqual(resp.id_, 44) self.assertEqual(resp.context, "ClientConnection") self.assertEqual(resp.type_, "Return") self.assertEqual(resp.value, dict(greeting="Hello thing"))
class TestSystemWSComms(unittest.TestCase): def setUp(self): sync_factory = SyncFactory("sync") self.process = Process("proc", sync_factory) block = Block("hello") self.process.add_block(block) HelloController(block) self.sc = WSServerComms("sc", self.process, 8888) self.process.start() self.sc.start() def tearDown(self): self.sc.stop() self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:8888/ws") req = dict(type="Post", id=0, endpoint=["hello", "say_hello"], 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="Return", value=dict(greeting="Hello me"))) conn.close() def test_server_and_simple_client(self): self.send_message() def test_server_with_malcolm_client(self): self.cc = WSClientComms("cc", self.process, "ws://localhost:8888/ws") self.cc.start() # Wait for comms to be connected while not self.cc.conn.done(): time.sleep(0.001) # Don't add to process as we already have a block of that name block2 = Block("hello") ClientController(self.process, block2, self.cc) ret = block2.say_hello("me2") self.assertEqual(ret, dict(greeting="Hello me2")) self.cc.stop()
class TestSystemWSCommsServerOnly(unittest.TestCase): socket = 8881 def setUp(self): self.sf = SyncFactory("sync") self.process = Process("proc", self.sf) block = Block() HelloController(self.process, block,'hello') self.sc = WSServerComms("sc", self.process, self.socket) self.process.start() self.sc.start() def tearDown(self): self.sc.stop() self.sc.wait() self.process.stop() @gen.coroutine def send_message(self): conn = yield websocket_connect("ws://localhost:%s/ws" % self.socket) req = dict( type="Post", id=0, endpoint=["hello", "say_hello"], 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="Return", value=dict( greeting="Hello me" ) )) conn.close() def test_server_and_simple_client(self): self.send_message()
def test_hello_with_process(self): sync_factory = SyncFactory("sched") process = Process("proc", sync_factory) b = Hello(process, dict(mri="hello"))[0] process.start() # wait until block is Ready task = Task("hello_ready_task", process) task.when_matches(b["state"], "Ready", timeout=1) q = sync_factory.create_queue() req = Post(response_queue=q, context="ClientConnection", endpoint=["hello", "greet"], parameters=dict(name="thing")) req.set_id(44) process.q.put(req) resp = q.get(timeout=1) self.assertEqual(resp.id, 44) self.assertEqual(resp.context, "ClientConnection") self.assertEqual(resp.typeid, "malcolm:core/Return:1.0") self.assertEqual(resp.value["greeting"], "Hello thing") process.stop()
class TestMethod(unittest.TestCase): def setUp(self): self.process = Process("proc") self.part = MyPart("test_part") self.controller = MyController(self.process, "mri", [self.part]) self.process.add_controller("mri", self.controller) self.context = Context(self.process) self.block = self.controller.make_view(self.context) self.process.start() self.process.my_method_executed = False def tearDown(self): self.process.stop(timeout=1) def test_post(self): method_view = self.block.my_method result = method_view.post(param1='testPost', param2='y') assert result.ret == 'testPosty' def test_post_async(self): method_view = self.block.my_method f = method_view.post_async('testAsync', 'y') assert f.result().ret == 'testAsyncy'
class TestController(unittest.TestCase): maxDiff = None def setUp(self): self.process = Process("proc") self.part = MyPart("test_part") self.part2 = MyPart("test_part2") self.o = MyController(self.process, "mri", [self.part, self.part2]) self.context = Context(self.process) self.process.start() def tearDown(self): self.process.stop(timeout=1) def test_init(self): assert self.o.mri == "mri" assert self.o.process == self.process def test_run_hook(self): context = MagicMock() context2 = MagicMock() part_contexts = {self.part: context, self.part2: context2} result = self.o.run_hook(self.o.TestHook, part_contexts) assert result == (dict(test_part=dict(foo="bar"), test_part2=dict(foo="bar"))) self.assertIs(self.part.context.anything, context.anything) del context del part_contexts gc.collect() with self.assertRaises(ReferenceError): self.part.context.anything def test_run_hook_raises(self): class MyException(Exception): pass context = MagicMock() context2 = MagicMock() self.part.exception = MyException() part_contexts = {self.part: context, self.part2: context2} with self.assertRaises(Exception) as cm: self.o.run_hook(self.o.TestHook, part_contexts) self.assertIs(self.part.context, None) self.assertIs(cm.exception, self.part.exception) def test_run_hook_aborted(self): context = MagicMock() context2 = MagicMock() part_contexts = {self.part: context, self.part2: context2} with patch.object(Queue, 'get', return_value=(self.part, AbortedError())): with self.assertRaises(AbortedError): self.o.run_hook(self.o.TestHook, part_contexts) def test_set_health(self): self.o.update_health(self.part, Alarm(severity=AlarmSeverity.MINOR_ALARM)) self.o.update_health(self.part2, Alarm(severity=AlarmSeverity.MAJOR_ALARM)) assert self.o.health.alarm.severity == AlarmSeverity.MAJOR_ALARM self.o.update_health(self.part, Alarm(severity=AlarmSeverity.UNDEFINED_ALARM)) self.o.update_health(self.part2, Alarm(severity=AlarmSeverity.INVALID_ALARM)) assert self.o.health.alarm.severity == AlarmSeverity.UNDEFINED_ALARM self.o.update_health(self.part) self.o.update_health(self.part2) assert self.o.health.value == "OK" def test_make_view(self): method_view = self.o._make_appropriate_view(self.context, self.part.my_method) attribute_view = self.o._make_appropriate_view(self.context, self.part.myAttribute) dict_view = self.o._make_appropriate_view(self.context, { 'a': self.part.myAttribute, 'm': self.part.my_method }) list_view = self.o._make_appropriate_view( self.context, [self.part.myAttribute, self.part.my_method]) model = Model() model_view = self.o._make_appropriate_view(self.context, model) none_view = self.o._make_appropriate_view(self.context, None) block_data = BlockModel() block_data.set_endpoint_data("attr", StringMeta().create_attribute_model()) block_data.set_endpoint_data("method", MethodModel()) block_data.set_notifier_path(MagicMock(), ["block"]) block_view = self.o._make_appropriate_view(self.context, block_data) # Todo check create_part_contexts worked self.o.create_part_contexts() # using __call__ assert method_view().ret == 'world' assert attribute_view.value == "hello_block" assert dict_view['a'].value == "hello_block" assert list_view[0].value == "hello_block" def test_handle_request(self): q = Queue() request = Get(id=41, path=["mri", "myAttribute"], callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 41 assert response.value["value"] == "hello_block" # It's part2 that will get the attribute as it was defined second self.part2.myAttribute.meta.writeable = False request = Put(id=42, path=["mri", "myAttribute"], value='hello_block', callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Error) # not writeable assert response.id == 42 self.part2.myAttribute.meta.writeable = True self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 42 assert response.value == "hello_block" request = Post(id=43, path=["mri", "my_method"], callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 43 assert response.value['ret'] == "world" # cover the controller._handle_post path for parameters request = Post(id=43, path=["mri", "my_method"], parameters={'dummy': 1}, callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 43 assert response.value['ret'] == "world" request = Subscribe(id=44, path=["mri", "myAttribute"], delta=False, callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Update) assert response.id == 44 assert response.value["typeid"] == "epics:nt/NTScalar:1.0" assert response.value["value"] == "hello_block" request = Unsubscribe(id=44, callback=q.put) self.o.handle_request(request) response = q.get(timeout=.1) self.assertIsInstance(response, Return) assert response.id == 44