def main(): service = Coordinator() longDelay = service.deadPings * 2 srv1 = ("localhost", 10001) srv2 = ("localhost", 10002) srv3 = ("localhost", 10003) currentView = 0 try: # no ready servers if service.master() is not None: raise TestFailedException("no ready servers") sys.stderr.write("Test passed: no ready servers\n") # first master for i in range(longDelay): info = service.ping(0, srv1) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv1, None, currentView, "first master") # first backup for i in range(longDelay): service.ping(currentView, srv1) info = service.ping(0, srv2) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv1, srv2, currentView, "first backup") # master fails, backup should take over service.ping(2, srv1) for i in range(longDelay): info = service.ping(2, srv2) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv2, None, currentView, "backup takes over") # first server restarts, should become backup for i in range(longDelay): service.ping(currentView, srv2) info = service.ping(0, srv1) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv2, srv1, currentView, "restarted server becomes backup") # master fails, third server appears, # backup should become master, new server - backup service.ping(currentView, srv2) for i in range(longDelay): service.ping(currentView, srv1) info = service.ping(0, srv3) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv1, srv3, currentView, "spare server becomes backup") # master quickly restarts, should not be master anymore service.ping(currentView, srv1) for i in range(longDelay): service.ping(0, srv1) info = service.ping(currentView, srv3) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv3, srv1, currentView, "master reboots") # set up a number with just 3 as master, # to prepare for the next test. for i in range(longDelay): info = service.ping(currentView, srv3) service.tick() currentView += 1 test(info, srv3, None, currentView, "master only") # backup appears but master does not ack for i in range(longDelay): service.ping(0, srv1) info = service.ping(currentView, srv3) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv3, srv1, currentView, "master doesn't ack") # master didn't ack and dies # check that backup is not promoted for i in range(longDelay): info = service.ping(currentView, srv1) if info.number == currentView + 1: break service.tick() test(info, srv3, srv1, currentView, "do not promote backup") # master finally acks for i in range(longDelay): service.ping(currentView, srv3) info = service.ping(currentView, srv1) if info.number == currentView + 1: break service.tick() test(info, srv3, srv1, currentView, "master acks") # backup suddenly restarts # should become backup anew for i in range(longDelay): service.ping(currentView, srv3) info = service.ping(0, srv1) if info.number == currentView + 1: break service.tick() currentView += 1 test(info, srv3, srv1, currentView, "backup reboots") except TestFailedException as e: sys.stderr.write("Test failed: %s\n" % e)