@Test
 public void commitSuccessfullyToTheFirstOne() throws Exception {
   MasterTxIdGenerator generator = newGenerator(3, 1, givenOrder());
   generator.committed(dataSource, 0, 2, null);
   assertCalls((FakeSlave) slaves.iterator().next(), 2l);
   assertNoFailureLogs();
 }
  private MasterTxIdGenerator newGenerator(
      int slaveCount, int replication, SlavePriority slavePriority, boolean... failingSlaves)
      throws Exception {
    slaves = instantiateSlaves(slaveCount, failingSlaves);
    dataSource = new FakeDataSource();

    log = new FakeStringLogger();
    Config config =
        new Config(MapUtil.stringMap(HaSettings.tx_push_factor.name(), "" + replication));
    Neo4jJobScheduler scheduler = new Neo4jJobScheduler();
    MasterTxIdGenerator result =
        new MasterTxIdGenerator(
            MasterTxIdGenerator.from(config, slavePriority),
            log,
            new Slaves() {
              @Override
              public Iterable<Slave> getSlaves() {
                return slaves;
              }
            },
            new CommitPusher(scheduler));
    // Life
    try {
      scheduler.init();
      scheduler.start();

      result.init();
      result.start();
    } catch (Throwable e) {
      throw Exceptions.launderedException(e);
    }
    return result;
  }
 @Test
 public void commitFailureAtFirstOneShouldMoveOnToNext() throws Exception {
   MasterTxIdGenerator generator = newGenerator(3, 1, givenOrder(), true);
   generator.committed(dataSource, 0, 2, null);
   Iterator<Slave> slaveIt = slaves.iterator();
   assertCalls((FakeSlave) slaveIt.next());
   assertCalls((FakeSlave) slaveIt.next(), 2);
   assertNoFailureLogs();
 }
 @Test
 public void commitACoupleOfTransactionsSuccessfully() throws Exception {
   MasterTxIdGenerator generator = newGenerator(3, 1, givenOrder());
   generator.committed(dataSource, 0, 2, null);
   generator.committed(dataSource, 0, 3, null);
   generator.committed(dataSource, 0, 4, null);
   assertCalls((FakeSlave) slaves.iterator().next(), 2, 3, 4);
   assertNoFailureLogs();
 }
 @Test
 public void notEnoughSlavesSuccessful() throws Exception {
   MasterTxIdGenerator generator = newGenerator(3, 2, givenOrder(), true, true);
   generator.committed(dataSource, 0, 2, null);
   Iterator<Slave> slaveIt = slaves.iterator();
   slaveIt.next();
   slaveIt.next();
   assertCalls((FakeSlave) slaveIt.next(), 2);
   assertFailureLogs();
 }
 @Test
 public void roundRobinSingleSlave() throws Exception {
   MasterTxIdGenerator generator = newGenerator(3, 1, roundRobin());
   for (long tx = 2; tx <= 6; tx++) {
     generator.committed(dataSource, 0, tx, null);
   }
   Iterator<Slave> slaveIt = slaves.iterator();
   assertCalls((FakeSlave) slaveIt.next(), 2, 5);
   assertCalls((FakeSlave) slaveIt.next(), 3, 6);
   assertCalls((FakeSlave) slaveIt.next(), 4);
   assertNoFailureLogs();
 }
 @Test
 public void commitSuccessfullyOnSomeOfThreeSlaves() throws Exception {
   MasterTxIdGenerator generator = newGenerator(5, 3, givenOrder(), false, true, true);
   generator.committed(dataSource, 0, 2, null);
   Iterator<Slave> slaveIt = slaves.iterator();
   assertCalls((FakeSlave) slaveIt.next(), 2);
   slaveIt.next();
   slaveIt.next();
   assertCalls((FakeSlave) slaveIt.next(), 2);
   assertCalls((FakeSlave) slaveIt.next(), 2);
   assertNoFailureLogs();
 }
  @Test
  public void roundRobinSomeFailing() throws Exception {
    MasterTxIdGenerator generator = newGenerator(4, 2, roundRobin(), false, true);
    for (long tx = 2; tx <= 6; tx++) {
      generator.committed(dataSource, 0, tx, null);
    }

    /* SLAVE |    TX
     *   0   | 2     5 6
     * F 1   |
     *   2   | 2 3 4   6
     *   3   |   3 4 5
     */
    Iterator<Slave> slaveIt = slaves.iterator();
    assertCalls((FakeSlave) slaveIt.next(), 2, 5, 6);
    slaveIt.next();
    assertCalls((FakeSlave) slaveIt.next(), 2, 3, 4, 6);
    assertCalls((FakeSlave) slaveIt.next(), 3, 4, 5);
    assertNoFailureLogs();
  }