### Question:
RecursivePeerRefreshState { void start(final List<DiscoveryPeer> initialPeers, final Bytes target) { if (iterativeSearchInProgress) { LOG.debug("Skip peer search because previous search is still in progress."); return; } LOG.debug("Start peer search."); iterativeSearchInProgress = true; this.target = target; currentRoundTimeout.ifPresent(RoundTimeout::cancelTimeout); currentRound = 0; oneTrueMap.clear(); addInitialPeers(initialPeers); bondingInitiateRound(); } RecursivePeerRefreshState(
      final BondingAgent bondingAgent,
      final FindNeighbourDispatcher neighborFinder,
      final TimerUtil timerUtil,
      final DiscoveryPeer localPeer,
      final PeerTable peerTable,
      final PeerDiscoveryPermissions peerPermissions,
      final int timeoutPeriodInSeconds,
      final int maxRounds);   }### Answer:
@Test public void shouldBondWithInitialNodesWhenStarted() { recursivePeerRefreshState.start(asList(peer1, peer2, peer3), TARGET); verify(bondingAgent).performBonding(peer1); verify(bondingAgent).performBonding(peer2); verify(bondingAgent).performBonding(peer3); verifyNoMoreInteractions(bondingAgent, neighborFinder); }
@Test public void shouldOnlyBondWithUnbondedInitialNodes() { peer1.setStatus(PeerDiscoveryStatus.BONDED); peer2.setStatus(PeerDiscoveryStatus.KNOWN); recursivePeerRefreshState.start(asList(peer1, peer2), TARGET); verify(bondingAgent).performBonding(peer2); verify(bondingAgent, never()).performBonding(peer1); verifyNoMoreInteractions(bondingAgent, neighborFinder); }
@Test public void shouldSkipStraightToFindNeighboursIfAllInitialNodesAreBonded() { peer1.setStatus(PeerDiscoveryStatus.BONDED); peer2.setStatus(PeerDiscoveryStatus.BONDED); recursivePeerRefreshState.start(asList(peer1, peer2), TARGET); verify(neighborFinder).findNeighbours(peer1, TARGET); verify(neighborFinder).findNeighbours(peer2, TARGET); verifyNoMoreInteractions(bondingAgent, neighborFinder); }
@Test public void shouldMoveToNeighboursRoundWhenBondingTimesOut() { peer1.setStatus(PeerDiscoveryStatus.BONDED); recursivePeerRefreshState.start(asList(peer1, peer2), TARGET); verify(bondingAgent).performBonding(peer2); timerUtil.runTimerHandlers(); verify(neighborFinder).findNeighbours(peer1, TARGET); verifyNoMoreInteractions(bondingAgent, neighborFinder); }
@Test public void shouldMoveToNeighboursRoundWhenBondingTimesOutVariant() { peer1.setStatus(PeerDiscoveryStatus.KNOWN); peer2.setStatus(PeerDiscoveryStatus.KNOWN); recursivePeerRefreshState.start(asList(peer1, peer2), TARGET); verify(bondingAgent).performBonding(peer1); verify(bondingAgent).performBonding(peer2); completeBonding(peer1); timerUtil.runTimerHandlers(); verify(neighborFinder).findNeighbours(peer1, TARGET); verify(neighborFinder, never()).findNeighbours(peer2, TARGET); }
@Test public void shouldNotQueryNodeMissingPermissions() { peer1.setStatus(PeerDiscoveryStatus.KNOWN); peer2.setStatus(PeerDiscoveryStatus.KNOWN); when(peerPermissions.allowOutboundNeighborsRequest(peer1)).thenReturn(false); recursivePeerRefreshState.start(asList(peer1, peer2), TARGET); verify(bondingAgent).performBonding(peer2); verify(bondingAgent).performBonding(peer2); completeBonding(peer1); completeBonding(peer2); verify(neighborFinder, times(0)).findNeighbours(peer1, TARGET); verify(neighborFinder, times(1)).findNeighbours(peer2, TARGET); }