@Test public void leasesLeadershipState() throws InterruptedException { LeadershipToken leasedToken = leased.blockOnBecomingLeader(); when(delegate.isStillLeading(token)).thenReturn(StillLeadingStatus.LEADING); assertThat(leased.isStillLeading(leasedToken)).isEqualTo(StillLeadingStatus.LEADING); assertThat(leased.isStillLeading(leasedToken)).isEqualTo(StillLeadingStatus.LEADING); verify(delegate).isStillLeading(token); }
for (int i = 0; i < MAX_NO_QUORUM_RETRIES; i++) { leading = leaderElectionService.isStillLeading(leadershipToken); if (leading != StillLeadingStatus.NO_QUORUM) { break;
private void loseLeadership(Callable proxy) throws InterruptedException { when(leaderElectionService.isStillLeading(any())) .thenReturn(LeaderElectionService.StillLeadingStatus.NOT_LEADING); when(leaderElectionService.blockOnBecomingLeader()).then(invocation -> { // never return LockSupport.park(); return null; }); // make a call so the proxy will realize that it has lost leadership assertThatThrownBy(proxy::call).isInstanceOf(NotCurrentLeaderException.class) .hasMessage("method invoked on a non-leader (leadership lost)"); }
@Before public void before() throws InterruptedException { when(leaderElectionService.blockOnBecomingLeader()).thenReturn(leadershipToken); when(leaderElectionService.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(leaderElectionService.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(leaderElectionService.isStillLeading(leadershipToken)).thenReturn( LeaderElectionService.StillLeadingStatus.LEADING); }
private LeasingLeadershipToken createLeaseToken(LeadershipToken token) throws InterruptedException { LeasingLeadershipToken wrapped = new LeasingLeadershipToken(token, leaseRefresh, () -> delegate.isStillLeading(token), leasingRequirements); NanoTime.sleepUntil(NanoTime.now().plus(leaseExpiry)); return wrapped; } }
@Test @SuppressWarnings("SelfEquals") // We're asserting that calling .equals on a proxy does not redirect // the .equals call to the instance its being proxied. public void shouldAllowObjectMethodsWhenLeading() { when(mockLeader.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(mockLeader.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(mockLeader.isStillLeading(any(LeaderElectionService.LeadershipToken.class))) .thenReturn(LeaderElectionService.StillLeadingStatus.LEADING); Runnable proxy = AwaitingLeadershipProxy.newProxyInstance(Runnable.class, delegateSupplier, mockLeader); assertThat(proxy.hashCode()).isNotNull(); assertThat(proxy.equals(proxy)).isTrue(); assertThat(proxy.equals(null)).isFalse(); assertThat(proxy.toString()).startsWith("com.palantir.leader.proxy.AwaitingLeadershipProxy@"); }
@Test @SuppressWarnings("SelfEquals") // We're asserting that calling .equals on a proxy does not redirect // the .equals call to the instance its being proxied. public void shouldAllowObjectMethodsWhenNotLeading() { when(mockLeader.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(mockLeader.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(mockLeader.isStillLeading(any(LeaderElectionService.LeadershipToken.class))) .thenReturn(LeaderElectionService.StillLeadingStatus.NOT_LEADING); Runnable proxy = AwaitingLeadershipProxy.newProxyInstance(Runnable.class, delegateSupplier, mockLeader); assertThat(proxy.hashCode()).isNotNull(); assertThat(proxy.equals(proxy)).isTrue(); assertThat(proxy.equals(null)).isFalse(); assertThat(proxy.toString()).startsWith("com.palantir.leader.proxy.AwaitingLeadershipProxy@"); }
@Test public void failsLoudlyIfWrongTypeOfLeadershipToken() { assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> leased.isStillLeading(token)); } }
public LeadershipToken gainLeadership(int leaderNum, boolean checkAfterwards) { LeaderElectionService.LeadershipToken token = null; try { token = leader(leaderNum).blockOnBecomingLeader(); } catch (InterruptedException e) { fail(e.getMessage()); } if (checkAfterwards) { assertEquals( "leader should still be leading right after becoming leader", StillLeadingStatus.LEADING, leader(leaderNum).isStillLeading(token)); } return token; }
@Test public void loseQuorum() { LeadershipToken token = state.gainLeadership(0); for (int i = 1; i < NUM_POTENTIAL_LEADERS - QUORUM_SIZE + 2; i++) { state.goDown(i); } assertNotSame("leader cannot maintain leadership without quorum", state.leader(0).isStillLeading(token), StillLeadingStatus.LEADING); state.comeUp(1); state.gainLeadership(0); assertNotSame("leader can confirm leadership with quorum", state.leader(0).isStillLeading(token), StillLeadingStatus.NOT_LEADING); }
for (int i = 0; i < MAX_NO_QUORUM_RETRIES; i++) { leading = leaderElectionService.isStillLeading(leadershipToken); if (leading != StillLeadingStatus.NO_QUORUM) { break;
private LeasingLeadershipToken createLeaseToken(LeadershipToken token) throws InterruptedException { LeasingLeadershipToken wrapped = new LeasingLeadershipToken(token, leaseRefresh, () -> delegate.isStillLeading(token), leasingRequirements); NanoTime.sleepUntil(NanoTime.now().plus(leaseExpiry)); return wrapped; } }