Ejemplo n.º 1
0
    def test_regr1(self):
        # test that if we send a Learner different accept messages for the same
        # proposal, it only accepts a majority vote
        n = self.node

        n.quorum_size = 3
        i = n.create_instance(1)
        i['status'] = "polling"
        n.recv_acceptnotify(
            Msg({
                'prop_num': (1, ''),
                'prop_value': 1,
                'uid': 1
            }), i)
        n.recv_acceptnotify(
            Msg({
                'prop_num': (1, ''),
                'prop_value': 1,
                'uid': 2
            }), i)
        n.recv_acceptnotify(
            Msg({
                'prop_num': (2, ''),
                'prop_value': 2,
                'uid': 3
            }), i)
        self.assertEqual(i['status'], "polling")
        n.recv_acceptnotify(
            Msg({
                'prop_num': (1, ''),
                'prop_value': 1,
                'uid': 4
            }), i)
        self.assertEqual(i['status'], "completed")
        self.assertEqual(i['value'], 1)
Ejemplo n.º 2
0
    def recv_prepare(self, msg, instance):
        """Update instance state appropriately based upon msg.

        (b) If an acceptor receives a prepare request with number n greater than that
        of any prepare request to which it has already responded, then it responds to
        the request with a promise not to accept any more proposals numbered less than
        n and with the highest-numbered proposal (if any) that it has accepted.
        """
        if msg.prop_num > instance['acceptor_prepare_prop_num']:
            self.writeMessage(
                msg['uid'],
                Msg({
                    'msg_type': 'promise',
                    'prop_num': msg['prop_num'],
                    'prev_prop_num': instance['acceptor_cur_prop_num'],
                    'prev_prop_value': instance['acceptor_cur_prop_value'],
                    'instance_id': instance['instance_id'],
                }))
            instance['acceptor_prepare_prop_num'] = msg.prop_num
        else:
            if config.NACKS_ENABLED:
                d = {
                    'msg_type': 'nack_promise',
                    'prop_num': msg['prop_num'],
                    'instance_id': instance['instance_id'],
                }
                if config.NACKS_ENABLED == 2:
                    d['prev_prop_num'] = instance['acceptor_cur_prop_num']
                    d['prev_prop_value'] = instance['acceptor_cur_prop_value']
                self.writeMessage(msg['uid'], Msg(d))
Ejemplo n.º 3
0
    def recv_acceptrequest(self, msg, instance):
        """Update instance state appropriately based upon msg.

        (b) If an acceptor receives an accept request for a proposal numbered n, it
        accepts the proposal unless it has already responded to a prepare request
        having a number greater than n.
        """
        if msg['prop_num'] >= instance['acceptor_prepare_prop_num']:
            dbprint("Instance %d: accepting prop %s (current is %s)" %
                    (instance['instance_id'], msg['prop_num'],
                     instance['acceptor_cur_prop_num']),
                    level=4)
            instance['acceptor_cur_prop_num'] = msg.prop_num
            instance['acceptor_cur_prop_value'] = msg.prop_value
            self.writeAll(
                Msg({
                    "msg_type": "acceptnotify",
                    "prop_num": msg.prop_num,
                    "prop_value": msg.prop_value,
                    "instance_id": instance['instance_id']
                }))
        else:
            if config.NACKS_ENABLED:
                d = {
                    'msg_type': 'nack_acceptrequest',
                    'prop_num': msg['prop_num'],
                    'instance_id': instance['instance_id'],
                }
                if config.NACKS_ENABLED == 2:
                    d['prev_prop_num'] = instance['acceptor_cur_prop_num']
                    d['prev_prop_value'] = instance['acceptor_cur_prop_value']
                self.writeMessage(msg['uid'], Msg(d))
Ejemplo n.º 4
0
 def test_promise2(self):
     """Test that we ignore lower numbered proposals than one we've already accepted"""
     i = self.node.create_instance(1)
     self.node.recv_prepare(Msg({'prop_num': (2, ''), "uid": 1}), i)
     self.transport.clear()
     self.node.recv_prepare(Msg({'prop_num': (1, ''), "uid": 1}), i)
     self.assertEqual('', self.transport.value())
Ejemplo n.º 5
0
    def test_prepare_timeout_responses(self):
        n = self.node
        i = n.create_instance(1)
        n.quorum_size = 2
        n.uid = ''

        n.proposer_start(i, "foo")
        n.recv_promise(
            Msg({
                'prop_num': (1, ''),
                'prev_prop_num': None,
                'prev_prop_value': None,
                'uid': 1
            }), i)
        n.recv_promise(
            Msg({
                'prop_num': (1, ''),
                'prev_prop_num': None,
                'prev_prop_value': None,
                'uid': 2
            }), i)

        self.assertEqual(i['our_val'], "foo")
        self.assertEqual(i['status'], "polling")
        self.assertEqual(i['last_tried'], (1, ''))
Ejemplo n.º 6
0
    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()))
Ejemplo n.º 7
0
    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]))
Ejemplo n.º 8
0
    def test_regr2(self):
        # test that if we send a Learner a bunch of accept messages from the same
        # acceptor, it only accepts a majority vote
        n = self.node

        n.quorum_size = 3
        i = n.create_instance(1)
        i['status'] = "polling"
        n.recv_acceptnotify(
            Msg({
                'prop_num': (1, ''),
                'prop_value': 1,
                'uid': 1
            }), i)
        n.recv_acceptnotify(
            Msg({
                'prop_num': (1, ''),
                'prop_value': 1,
                'uid': 1
            }), i)
        n.recv_acceptnotify(
            Msg({
                'prop_num': (2, ''),
                'prop_value': 2,
                'uid': 1
            }), i)
        self.assertEqual(i['status'], "polling")
Ejemplo n.º 9
0
 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()))
Ejemplo n.º 10
0
 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()))
Ejemplo n.º 11
0
 def test_errors(self):
     self.assertRaises(InvalidMessageException, parse_message,
                       Msg({
                           "msg_type": "foobar",
                           "proposal": "1,2"
                       }))
     self.assertRaises(InvalidMessageException, parse_message,
                       Msg({
                           "msg_type": "promise",
                           "proposal": "1"
                       }))
Ejemplo n.º 12
0
 def discoverNetwork(self):
     if config.STARTUP == "old":
         if self.bootstrap is not None:
             m = Msg({"msg_type": "ehlo", "uid": self.uid, "instance_id": None})
             self.transport.write(m.serialize(), self.bootstrap)
     else:
         if self.bootstrap is not None:
             m = Msg({"msg_type": "hi", "uid": self.uid, "instance_id": None})
             self.transport.write(m.serialize(), self.bootstrap)
         else:
             self.master = ("localhost", self.transport.getHost().port)
             self.hosts[self.uid] = self.master
Ejemplo n.º 13
0
 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()))
Ejemplo n.º 14
0
 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()))
Ejemplo n.º 15
0
 def recv_ping(self, msg, instance):
     """Reply to a PING with a PONG (as a heartbeat)"""
     self.writeMessage(msg['uid'],
                       Msg({
                           "msg_type": "pong",
                           "instance_id": None
                       }))
Ejemplo n.º 16
0
 def send_acceptrequest(self, uid, prop_num, value, instance):
     d = {
         "msg_type": "acceptrequest",
         "prop_num": prop_num,
         "prop_value": value,
         "instance_id": instance['instance_id']
     }
     self.writeMessage(uid, Msg(d))
Ejemplo n.º 17
0
 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]))
Ejemplo n.º 18
0
 def write_who(self, uid):
     self.check_startup_style("new")
     self.writeMessage(
         uid,
         Msg({
             "msg_type": "who",
             "hosts": self.hosts,
             "instance_id": None
         }))
Ejemplo n.º 19
0
 def test_unknown_instance(self):
     self.node.datagramReceived(
         Msg({
             'msg_type': "prepare",
             'uid': 1,
             'instance_id': 500,
             'prop_num': (1, ''),
             'prop_value': None
         }).serialize(), None)
     self.assertTrue(self.node.instances[500])
Ejemplo n.º 20
0
 def write_new(self, n_uid, t_uid):
     self.check_startup_style("new")
     self.writeMessage(
         t_uid,
         Msg({
             "msg_type": "new",
             "new_uid": n_uid,
             "new_address": self.hosts[n_uid],
             "instance_id": None
         }))
Ejemplo n.º 21
0
 def write_notify(self, uid):
     """Send a NOTIFY message with all the hosts we know about."""
     self.check_startup_style("old")
     self.writeMessage(
         uid,
         Msg({
             "msg_type": "notify",
             "hosts": self.hosts,
             "instance_id": None
         }))
Ejemplo n.º 22
0
 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()))
Ejemplo n.º 23
0
 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))
Ejemplo n.º 24
0
 def test_unknown_host(self):
     self.node.datagramReceived(
         Msg({
             'msg_type': "pong",
             'uid': 100,
             'instance_id': None
         }).serialize(), None)
     self.assertTrue(100 in self.node.hosts)
     self.assertEqual(self.node.hosts[100], None)
     self.node.datagramReceived(
         Msg({
             'msg_type': "pong",
             'uid': 101,
             'instance_id': None
         }).serialize(), None)
     self.node.datagramReceived(
         Msg({
             'msg_type': "pong",
             'uid': 102,
             'instance_id': None
         }).serialize(), None)
     self.assertEqual(self.node.quorum_size, 7)
Ejemplo n.º 25
0
    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]))
Ejemplo n.º 26
0
    def timeout_test(self, init=False):
        # If this isn't the first time we've run, do some pruning
        if not init:
            # Remove any hosts we haven't heard from yet
            for h in self.timeout_hosts:
                self.hosts.pop(h, None)

        # Start again
        self.timeout_hosts = dict(self.hosts)
        for h in self.hosts:
            self.writeMessage(h, Msg({
                "msg_type": "ping",
                "instance_id": None
            }))
        self.reactor.callLater(self.timeout, self.timeout_test)
Ejemplo n.º 27
0
    def proposer_start(self, instance, value, prop_num=1, restart=True):
        """Start an instance of Paxos!

        Try and complete an instance of Paxos, setting the decree to value.
        """
        # (a) A proposer selects a proposal number n, greater than any proposal number it
        # has selected before, and sends a request containing n to a majority of
        # acceptors. This message is known as a prepare request.
        instance['our_val'] = value
        instance['status'] = "trying"
        p = (prop_num, self.uid)
        instance['last_tried'] = p
        instance['restart'] = restart
        self.writeAll(
            Msg({
                "msg_type": "prepare",
                "prop_num": p,
                "instance_id": instance['instance_id']
            }))
        self.reactor.callLater(self.proposer_timeout,
                               self.handle_proposer_timeout, instance,
                               "trying")
Ejemplo n.º 28
0
 def discoverNetwork(self):
     if config.STARTUP == "old":
         if self.bootstrap is not None:
             m = Msg({
                 "msg_type": "ehlo",
                 "uid": self.uid,
                 "instance_id": None
             })
             self.transport.write(m.serialize(), self.bootstrap)
     else:
         if self.bootstrap is not None:
             m = Msg({
                 "msg_type": "hi",
                 "uid": self.uid,
                 "instance_id": None
             })
             self.transport.write(m.serialize(), self.bootstrap)
         else:
             self.master = ("localhost", self.transport.getHost().port)
             self.hosts[self.uid] = self.master
Ejemplo n.º 29
0
 def test_timeout(self):
     self.clock.advance(self.node.timeout)
     self.node.recv_pong(Msg({"uid": 1}), None)
     self.node.recv_pong(Msg({"uid": 2}), None)
     self.clock.advance(self.node.timeout)
     self.assertEqual(self.node.hosts, {1: 1, 2: 2})
Ejemplo n.º 30
0
 def test_receive_ping(self):
     self.node.recv_ping(Msg({"uid": 1}), None)
     self.assertMsg(Msg({"msg_type": "pong"}),
                    parse_message(self.transport.value()))
Ejemplo n.º 31
0
 def test_receive(self):
     """Test all agents can receive any message without crashing"""
     a = self.node
     a.datagramReceived(
         Msg({
             'msg_type': "prepare",
             'uid': 1,
             'instance_id': 1,
             'prop_num': (1, ''),
             'prop_value': None
         }).serialize(), None)
     #a.datagramReceived(Msg({'msg_type': "promise", 'uid': 1, 'prev_prop_value': None, 'prev_prop_num': 0, 'instance_id': 1, 'prop_num':  (1, ''), 'prop_value': None}).serialize(), None)
     a.datagramReceived(
         Msg({
             'msg_type': "acceptnotify",
             'uid': 1,
             'instance_id': 1,
             'prop_num': (1, ''),
             'prop_value': None
         }).serialize(), None)
     a.datagramReceived(
         Msg({
             'msg_type': "acceptrequest",
             'uid': 1,
             'instance_id': 1,
             'prop_num': (1, ''),
             'prop_value': None
         }).serialize(), None)
     a.datagramReceived(
         Msg({
             'msg_type': "prepare",
             'uid': 1,
             'instance_id': 1,
             'prop_num': (1, ''),
             'prop_value': 2
         }).serialize(), None)
     a.datagramReceived(
         Msg({
             'msg_type': "promise",
             'uid': 1,
             'instance_id': 1,
             'prev_prop_value': None,
             'prev_prop_num': 0,
             'prop_num': (1, ''),
             'prop_value': 2
         }).serialize(), None)
     a.datagramReceived(
         Msg({
             'msg_type': "acceptnotify",
             'uid': 1,
             'instance_id': 1,
             'prop_num': (1, ''),
             'prop_value': 2
         }).serialize(), None)
     a.datagramReceived(
         Msg({
             'msg_type': "acceptrequest",
             'uid': 1,
             'instance_id': 1,
             'prop_num': (1, ''),
             'prop_value': 2
         }).serialize(), None)