/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.voltcore.agreement;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.FailureSiteForwardMessage;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.SiteFailureMessage;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.fsfmMsg;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.sfmFailed;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.sfmFailures;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.sfmSafe;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.sfmSafeTxns;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.sfmSource;
import static org.voltcore.agreement.maker.SiteFailureMessageMaker.sfmSurvivors;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.voltcore.messaging.SiteFailureMessage;
import com.google_voltpatches.common.collect.ImmutableMap;
import com.google_voltpatches.common.collect.ImmutableSet;
import com.google_voltpatches.common.primitives.Longs;
import com.natpryce.makeiteasy.Maker;
@SuppressWarnings("unchecked")
public class TestAgreementSeeker {
AgreementSeeker s1 = new AgreementSeeker(ArbitrationStrategy.MATCHING_CARDINALITY,1);
AgreementSeeker s2 = new AgreementSeeker(ArbitrationStrategy.MATCHING_CARDINALITY,2);
AgreementSeeker s3 = new AgreementSeeker(ArbitrationStrategy.MATCHING_CARDINALITY,3);
AgreementSeeker s4 = new AgreementSeeker(ArbitrationStrategy.MATCHING_CARDINALITY,4);
final static Set<Long> hsids = ImmutableSet.of(1L,2L,3L,4L);
@Before
public void setUp() throws Exception {
}
@Test
public void testOneNodeDown() throws Exception {
Maker<SiteFailureMessage> s2fail = a(SiteFailureMessage,
with(sfmSurvivors,Longs.asList(1,3,4)),
with(sfmSafeTxns,sfmSafe(2,22)),
with(sfmFailures,sfmFailed(2)));
s1.startSeekingFor(hsids, ImmutableMap.of(2L,true));
s3.startSeekingFor(hsids, ImmutableMap.of(2L,true));
s4.startSeekingFor(hsids, ImmutableMap.of(2L,true));
s1.add(make(s2fail.but(with(sfmSource,1L))));
s1.add(make(s2fail.but(with(sfmSource,3L))));
s1.add(make(s2fail.but(with(sfmSource,4L))));
s3.add(make(s2fail.but(with(sfmSource,1L))));
s3.add(make(s2fail.but(with(sfmSource,3L))));
s3.add(make(s2fail.but(with(sfmSource,4L))));
s4.add(make(s2fail.but(with(sfmSource,1L))));
s4.add(make(s2fail.but(with(sfmSource,3L))));
s4.add(make(s2fail.but(with(sfmSource,4L))));
assertThat(s1.nextKill(), contains(2L));
assertThat(s3.nextKill(), contains(2L));
assertThat(s4.nextKill(), contains(2L));
assertThat(s1.needForward(), equalTo(false));
assertThat(s3.needForward(), equalTo(false));
assertThat(s4.needForward(), equalTo(false));
assertThat(s1.forWhomSiteIsDead(2L),empty());
assertThat(s3.forWhomSiteIsDead(2L),empty());
assertThat(s4.forWhomSiteIsDead(2L),empty());
}
@Test
public void testTwoNodesDown() throws Exception {
Maker<SiteFailureMessage> s23fail = a(SiteFailureMessage,
with(sfmSurvivors,Longs.asList(1,4)),
with(sfmSafeTxns,sfmSafe(2,22,3,33)),
with(sfmFailures,sfmFailed(2,3)));
s1.startSeekingFor(hsids, ImmutableMap.of(2L,true,3L,true));
s4.startSeekingFor(hsids, ImmutableMap.of(2L,true,3L,true));
s1.add(make(s23fail.but(with(sfmSource,1L))));
s1.add(make(s23fail.but(with(sfmSource,4L))));
s4.add(make(s23fail.but(with(sfmSource,1L))));
s4.add(make(s23fail.but(with(sfmSource,4L))));
assertThat(s1.nextKill(), contains(2L,3L));
assertThat(s4.nextKill(), contains(2L,3L));
assertThat(s1.needForward(), equalTo(false));
assertThat(s4.needForward(), equalTo(false));
assertThat(s1.forWhomSiteIsDead(2L),empty());
assertThat(s1.forWhomSiteIsDead(3L),empty());
assertThat(s4.forWhomSiteIsDead(2L),empty());
assertThat(s4.forWhomSiteIsDead(3L),empty());
}
@Test
public void testOneLinkDownBetweenTwoNodes() throws Exception {
Maker<SiteFailureMessage> msg = a(SiteFailureMessage,
with(sfmSurvivors,Longs.asList(1,2,3,4)),
with(sfmSafeTxns,sfmSafe(3,33,4,44)),
with(sfmFailures,sfmFailed(3,4)));
s1.startSeekingFor(hsids, ImmutableMap.of(3L,false,4L,false));
s2.startSeekingFor(hsids, ImmutableMap.of(3L,false,4L,false));
s3.startSeekingFor(hsids, ImmutableMap.of(3L,false,4L,true));
s4.startSeekingFor(hsids, ImmutableMap.of(3L,true,4L,false));
s1.add(make(msg.but(with(sfmSource,1L))));
s1.add(make(msg.but(with(sfmSource,2L))));
s1.add(make(msg.but(with(sfmSource,3L),with(sfmSurvivors,Longs.asList(1,2,3)))));
s1.add(make(msg.but(with(sfmSource,4L),with(sfmSurvivors,Longs.asList(1,2,4)))));
s2.add(make(msg.but(with(sfmSource,1L))));
s2.add(make(msg.but(with(sfmSource,2L))));
s2.add(make(msg.but(with(sfmSource,3L),with(sfmSurvivors,Longs.asList(1,2,3)))));
s2.add(make(msg.but(with(sfmSource,4L),with(sfmSurvivors,Longs.asList(1,2,4)))));
s3.add(make(msg.but(with(sfmSource,1L))));
s3.add(make(msg.but(with(sfmSource,2L))));
s3.add(make(msg.but(with(sfmSource,3L),with(sfmSurvivors,Longs.asList(1,2,3)))));
s4.add(make(msg.but(with(sfmSource,1L))));
s4.add(make(msg.but(with(sfmSource,2L))));
s4.add(make(msg.but(with(sfmSource,3L),with(sfmSurvivors,Longs.asList(1,2,4)))));
assertThat(s1.needForward(), equalTo(false));
assertThat(s2.needForward(), equalTo(false));
assertThat(s3.needForward(), equalTo(true));
assertThat(s4.needForward(), equalTo(true));
assertThat(s1.forWhomSiteIsDead(4L),contains(3L));
assertThat(s1.forWhomSiteIsDead(3L),contains(4L));
assertThat(s2.forWhomSiteIsDead(4L),contains(3L));
assertThat(s2.forWhomSiteIsDead(3L),contains(4L));
assertThat(s2.forWhomSiteIsDead(2L),empty());
assertThat(s3.forWhomSiteIsDead(4L),empty());
assertThat(s4.forWhomSiteIsDead(3L),empty());
assertThat(s4.forWhomSiteIsDead(4L),empty());
s3.add(make(a(FailureSiteForwardMessage,
with(fsfmMsg, msg.but(with(sfmSource,4L),with(sfmSurvivors,Longs.asList(1,2,4)))))));
s4.add(make(a(FailureSiteForwardMessage,
with(fsfmMsg, msg.but(with(sfmSource,3L),with(sfmSurvivors,Longs.asList(1,2,3)))))));
assertThat(s3.needForward(), equalTo(false));
assertThat(s4.needForward(), equalTo(false));
assertThat(s1.nextKill(), contains(4L));
assertThat(s2.nextKill(), contains(4L));
assertThat(s3.nextKill(), contains(4L));
assertThat(s4.nextKill(), contains(3L));
}
}