def test_promise_onevalue(self): # promises - one value - send orig value n = self.node i = n.create_instance(1) i['status'] = "trying" i['last_tried'] = (2, '') n.quorum_size = 2 n.recv_promise( Msg({ 'prop_num': (2, ''), 'prev_prop_num': None, 'prev_prop_value': None, 'uid': 1 }), i) self.assertEqual('', self.transport.value()) n.recv_promise( Msg({ 'prop_num': (2, ''), 'prev_prop_num': 1, 'prev_prop_value': 1, 'uid': 2 }), i) self.assertMsg( Msg({ "msg_type": "acceptrequest", "prop_num": (2, ''), "prop_value": 1 }), parse_message(self.transport.msgs[0])) self.assertMsg( Msg({ "msg_type": "acceptrequest", "prop_num": (2, ''), "prop_value": 1 }), parse_message(self.transport.msgs[1]))
def test_promise4(self): """Test that we respond with any proposal we've accepted""" i = self.node.create_instance(1) self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i) res = Msg({ 'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (1, ''), 'prev_prop_num': 0 }) self.assertMsg(res, parse_message(self.transport.value())) self.transport.clear() self.node.recv_acceptrequest( Msg({ 'prop_num': (1, ''), 'prop_value': 2, "uid": 1 }), i) self.transport.clear() self.node.recv_prepare(Msg({'prop_num': (2, ''), "uid": 1}), i) res = Msg({ 'prev_prop_value': 2, 'msg_type': 'promise', 'prop_num': (2, ''), 'prev_prop_num': (1, '') }) self.assertMsg(res, parse_message(self.transport.value()))
def test_promise3(self): """Test that we accept new, higher numbered proposals than ones we've already accepted""" i = self.node.create_instance(1) self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i) res = Msg({'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (1, ''), 'prev_prop_num': 0}) self.assertMsg(res, parse_message(self.transport.value())) self.transport.clear() self.node.recv_prepare(Msg({'prop_num': (2, ''), "uid": 1}), i) res = Msg({'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (2, ''), 'prev_prop_num': 0}) self.assertMsg(res, parse_message(self.transport.value()))
def test_promise4(self): """Test that we respond with any proposal we've accepted""" i = self.node.create_instance(1) self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i) res = Msg({'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (1, ''), 'prev_prop_num': 0}) self.assertMsg(res, parse_message(self.transport.value())) self.transport.clear() self.node.recv_acceptrequest(Msg({'prop_num': (1, ''), 'prop_value': 2, "uid": 1}), i) self.transport.clear() self.node.recv_prepare(Msg({'prop_num': (2, ''), "uid": 1}), i) res = Msg({'prev_prop_value': 2, 'msg_type': 'promise', 'prop_num': (2, ''), 'prev_prop_num': (1, '')}) self.assertMsg(res, parse_message(self.transport.value()))
def datagramReceived(self, msg, host): """Called when a message is received by a specific agent. """ self._msgs.append((msg, host)) try: m = parse_message(msg) # If we haven't heard this host before, add them to the record if m['uid'] not in self.hosts and m['uid'] != self.uid: self.addHost(m['uid'], host) t = m['msg_type'] dbprint("Got %s message from %s\n%s\n" % (m['msg_type'], host, m), level=1) if m['instance_id'] is not None: i = m['instance_id'] if i not in self.instances: if i >= self.current_instance_number: self.current_instance_number = i+1 self.instances[i] = self.create_instance(i) else: assert i < self.current_instance_number, "known but oddly large instance number %s (%s)" % (i, self.current_instance_number) instance = self.instances[i] if instance['status'] == 'completed': dbprint("dropping msg as instance %s is already completed" % i, level=2) return else: instance = None method = getattr(self, "recv_%s" % t) method(m, instance) except (InvalidMessageException, KeyError), e: dbprint("%s received invalid message %s (%s)" % (self, msg, e), level=4) raise
def test_autodiscover(self): self.node.bootstrap = object() self.node.discoverNetwork() self.assertMsg(Msg({ "msg_type": "ehlo", "instance_id": None }), parse_message(self.transport.value()))
def test_receive_ehlo(self): self.node.recv_ehlo(Msg({"uid": 1}), None) self.assertMsg( Msg({ "msg_type": "notify", "hosts": self.node.hosts, "instance_id": None }), parse_message(self.transport.value()))
def test_promise(self): i = self.node.create_instance(1) self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i) res = Msg({ 'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (1, ''), 'prev_prop_num': 0 }) self.assertMsg(res, parse_message(self.transport.value()))
def test_promise3(self): """Test that we accept new, higher numbered proposals than ones we've already accepted""" i = self.node.create_instance(1) self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i) res = Msg({ 'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (1, ''), 'prev_prop_num': 0 }) self.assertMsg(res, parse_message(self.transport.value())) self.transport.clear() self.node.recv_prepare(Msg({'prop_num': (2, ''), "uid": 1}), i) res = Msg({ 'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (2, ''), 'prev_prop_num': 0 }) self.assertMsg(res, parse_message(self.transport.value()))
def test_run(self): n = self.node n.uid = 1 n.run("foo") for m in self.transport.msgs: self.assertMsg( Msg({ 'msg_type': "prepare", 'uid': 1, 'instance_id': 1, 'prop_num': (1, 1) }), parse_message(m))
def test_receive_notify(self): self.node.recv_notify( Msg({ 'msg_type': "notify", "uid": 1, "hosts": { "foo": "bar" } }), None) self.assertEqual(self.node.hosts["foo"], "bar") self.assertMsg(Msg({ "msg_type": "ehlo", "instance_id": None }), parse_message(self.transport.value()))
def test_promise_multiple_values2(self): # promises - multiple values - send highest value # (same as test_promise_multiple_values but in reverse order) n = self.node i = n.create_instance(1) i['status'] = "trying" i['last_tried'] = (3, '') n.quorum_size = 2 n.recv_promise( Msg({ 'prop_num': (3, ''), 'prev_prop_num': (2, ''), 'prev_prop_value': 6, 'uid': 2 }), i) self.assertEqual('', self.transport.value()) n.recv_promise( Msg({ 'prop_num': (3, ''), 'prev_prop_num': (1, ''), 'prev_prop_value': 5, 'uid': 1 }), i) self.assertMsg( Msg({ "msg_type": "acceptrequest", "prop_num": (3, ''), "prop_value": 6 }), parse_message(self.transport.msgs[0])) self.assertMsg( Msg({ "msg_type": "acceptrequest", "prop_num": (3, ''), "prop_value": 6 }), parse_message(self.transport.msgs[1]))
def test_accept(self): """Test that on proposal acceptance the Node notifies all other nodes about its decision""" i = self.node.create_instance(1) self.node.recv_acceptrequest( Msg({ 'prop_num': (1, ''), 'prop_value': 2, "uid": 1 }), i) self.assertEqual((1, ''), i['acceptor_cur_prop_num']) for x in xrange(10): self.assertMsg( Msg({ "msg_type": "acceptnotify", "prop_num": (1, ''), "prop_value": 2 }), parse_message(self.transport.msgs[x]))
def datagramReceived(self, msg, host): """Called when a message is received by a specific agent. """ self._msgs.append((msg, host)) try: m = parse_message(msg) # If we haven't heard this host before, add them to the record if m['uid'] not in self.hosts and m['uid'] != self.uid: self.addHost(m['uid'], host) t = m['msg_type'] dbprint("Got %s message from %s\n%s\n" % (m['msg_type'], host, m), level=1) if m['instance_id'] is not None: i = m['instance_id'] if i not in self.instances: if i >= self.current_instance_number: self.current_instance_number = i + 1 self.instances[i] = self.create_instance(i) else: assert i < self.current_instance_number, "known but oddly large instance number %s (%s)" % ( i, self.current_instance_number) instance = self.instances[i] if instance['status'] == 'completed': dbprint( "dropping msg as instance %s is already completed" % i, level=2) return else: instance = None method = getattr(self, "recv_%s" % t) method(m, instance) except (InvalidMessageException, KeyError), e: dbprint("%s received invalid message %s (%s)" % (self, msg, e), level=4) raise
def test_receive_ping(self): self.node.recv_ping(Msg({"uid": 1}), None) self.assertMsg(Msg({"msg_type": "pong"}), parse_message(self.transport.value()))
def test_promise_multiple_values2(self): # promises - multiple values - send highest value # (same as test_promise_multiple_values but in reverse order) n = self.node i = n.create_instance(1) i['status'] = "trying" i['last_tried'] = (3, '') n.quorum_size = 2 n.recv_promise(Msg({'prop_num': (3, ''), 'prev_prop_num': (2, ''), 'prev_prop_value': 6, 'uid': 2}), i) self.assertEqual('', self.transport.value()) n.recv_promise(Msg({'prop_num': (3, ''), 'prev_prop_num': (1, ''), 'prev_prop_value': 5, 'uid': 1}), i) self.assertMsg(Msg({"msg_type": "acceptrequest", "prop_num": (3, ''), "prop_value": 6}), parse_message(self.transport.msgs[0])) self.assertMsg(Msg({"msg_type": "acceptrequest", "prop_num": (3, ''), "prop_value": 6}), parse_message(self.transport.msgs[1]))
def test_accept(self): """Test that on proposal acceptance the Node notifies all other nodes about its decision""" i = self.node.create_instance(1) self.node.recv_acceptrequest(Msg({'prop_num': (1, ''), 'prop_value': 2, "uid": 1}), i) self.assertEqual((1, ''), i['acceptor_cur_prop_num']) for x in xrange(10): self.assertMsg(Msg({"msg_type": "acceptnotify", "prop_num": (1, ''), "prop_value": 2}), parse_message(self.transport.msgs[x]))
def test_autodiscover(self): self.node.bootstrap = object() self.node.discoverNetwork() self.assertMsg(Msg({"msg_type": "ehlo", "instance_id": None}), parse_message(self.transport.value()))
def test_receive_ehlo(self): self.node.recv_ehlo(Msg({"uid": 1}), None) self.assertMsg(Msg({"msg_type": "notify", "hosts": self.node.hosts, "instance_id": None}), parse_message(self.transport.value()))
def test_promise(self): i = self.node.create_instance(1) self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i) res = Msg({'prev_prop_value': None, 'msg_type': 'promise', 'prop_num': (1, ''), 'prev_prop_num': 0}) self.assertMsg(res, parse_message(self.transport.value()))
def test_run(self): n = self.node n.uid = 1 n.run("foo") for m in self.transport.msgs: self.assertMsg(Msg({'msg_type': "prepare", 'uid': 1, 'instance_id': 1, 'prop_num': (1, 1)}), parse_message(m))
def test_promise_onevalue(self): # promises - one value - send orig value n = self.node i = n.create_instance(1) i['status'] = "trying" i['last_tried'] = (2, '') n.quorum_size = 2 n.recv_promise(Msg({'prop_num': (2, ''), 'prev_prop_num': None, 'prev_prop_value': None, 'uid': 1}), i) self.assertEqual('', self.transport.value()) n.recv_promise(Msg({'prop_num': (2, ''), 'prev_prop_num': 1, 'prev_prop_value': 1, 'uid': 2}), i) self.assertMsg(Msg({"msg_type": "acceptrequest", "prop_num": (2, ''), "prop_value": 1}), parse_message(self.transport.msgs[0])) self.assertMsg(Msg({"msg_type": "acceptrequest", "prop_num": (2, ''), "prop_value": 1}), parse_message(self.transport.msgs[1]))
def test_receive_notify(self): self.node.recv_notify(Msg({'msg_type': "notify", "uid": 1, "hosts": {"foo": "bar"}}), None) self.assertEqual(self.node.hosts["foo"], "bar") self.assertMsg(Msg({"msg_type": "ehlo", "instance_id": None}), parse_message(self.transport.value()))