Example #1
0
  void clear() {
    for (Iterator i = map.keySet().iterator(); i.hasNext(); ) {
      ByteArray a = (ByteArray) i.next();
      a.clear();
      wrappers.push(a);
    }

    map.clear();
  }
Example #2
0
  private static SetInfo parseSet(Node parent) throws XmlParserException {
    String id = "";
    String type = "";
    String measurementids = null;

    NodeList nodes = parent.getChildNodes();
    Vector<SetInfo> sets = new Vector<SetInfo>();
    for (int nodeid = 0; nodeid < nodes.getLength(); ++nodeid) {
      Node node = nodes.item(nodeid);
      if (node.getNodeType() != Node.ELEMENT_NODE) continue;

      Element element = (Element) node;
      if (element.getTagName().equals("id")) id = element.getTextContent();
      else if (element.getTagName().equals("set")) sets.add(parseSet(element));
      else if (element.getTagName().equals("type")) type = element.getTextContent();
      else if (element.getTagName().equals("measurementids"))
        measurementids = element.getTextContent();
    }

    // create the set
    SetInfo set = new SetInfo(id, Integer.parseInt(type));
    if (measurementids != null) {
      int mids[] = ByteArray.toIntArray(Base64.decode(measurementids), ByteArray.ENDIAN_LITTLE, 32);
      for (int mid : mids) set.addMeasurementID(mid);
    }

    // add the children
    for (SetInfo s : sets) set.addChild(s);

    return set;
  }
Example #3
0
 /** test for method vote(..) */
 public void testVote() {
   V1Poll p = testV1polls[1];
   p.m_hash = ByteArray.makeRandomBytes(20);
   try {
     p.castOurVote();
   } catch (IllegalStateException e) {
     // the socket isn't inited and should squack
   }
   p.m_pollstate = V1Poll.PS_COMPLETE;
 }
Example #4
0
  /** test for method checkVote(..) */
  public void testCheckVote() throws Exception {
    V1LcapMessage msg = null;
    log.debug3("starting testCheeckVote");
    msg =
        V1LcapMessage.makeReplyMsg(
            testV1polls[0].getMessage(),
            ByteArray.makeRandomBytes(20),
            ByteArray.makeRandomBytes(20),
            null,
            V1LcapMessage.NAME_POLL_REP,
            testduration,
            testID);
    log.debug3("testCheeckVote 2");
    V1Poll p = null;
    p = createCompletedPoll(theDaemon, testau, msg, 8, 2, pollmanager);
    assertTrue(p instanceof V1NamePoll);
    log.debug3("testCheeckVote 3");
    assertNotNull(p);
    PeerIdentity id = msg.getOriginatorId();
    assertNotNull(id);
    assertNotNull(p.m_tally);
    int rep = p.m_tally.wtAgree + idmgr.getReputation(id);

    // good vote check

    p.checkVote(msg.getHashed(), new Vote(msg, false));
    assertEquals(9, p.m_tally.numAgree);
    assertEquals(2, p.m_tally.numDisagree);
    assertEquals(rep, p.m_tally.wtAgree);

    rep = p.m_tally.wtDisagree + idmgr.getReputation(id);

    // bad vote check
    p.checkVote(ByteArray.makeRandomBytes(20), new Vote(msg, false));
    assertEquals(9, p.m_tally.numAgree);
    assertEquals(3, p.m_tally.numDisagree);
    assertEquals(rep, p.m_tally.wtDisagree);
  }
Example #5
0
  int contains(BytecodeBuffer b, int start, int end) {
    key.clear();
    key.b = b;
    key.start = start;
    key.end = end;
    key.hash = 0;
    key.init();

    Integer index = (Integer) map.get(key);
    return (index != null) ? index.intValue() : -1;
  }
Example #6
0
 public void testDiskRepairMessage() throws Exception {
   int len = 100 * 1024;
   byte[] repairData = ByteArray.makeRandomBytes(len);
   V3LcapMessage src = makeRepairMessage(repairData);
   assertEquals(len, src.getRepairDataLength());
   assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH + len, src.getEstimatedEncodedLength());
   InputStream srcStream = src.getInputStream();
   V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
   assertEqualMessages(src, copy);
   assertEquals(len, copy.getRepairDataLength());
   assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH + len, src.getEstimatedEncodedLength());
   InputStream in = copy.getRepairDataInputStream();
   assertTrue(in + "", in instanceof FileInputStream);
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   StreamUtil.copy(in, out);
   byte[] repairCopy = out.toByteArray();
   assertEquals(repairData, repairCopy);
   // ensure that repeated delete doesn't cause error
   copy.delete();
   copy.delete();
 }
Example #7
0
  /** test for method voteInPoll(..) */
  public void testVoteInPoll() {
    V1Poll p = testV1polls[1];
    p.m_tally.quorum = 10;
    p.m_tally.numAgree = 5;
    p.m_tally.numDisagree = 2;
    p.m_tally.wtAgree = 2000;
    p.m_tally.wtDisagree = 200;
    p.m_hash = ByteArray.makeRandomBytes(20);
    try {
      p.voteInPoll();
    } catch (IllegalStateException e) {
      // the socket isn't inited and should squack
    }

    p.m_tally.numAgree = 20;
    try {
      p.voteInPoll();
    } catch (NullPointerException npe) {
      // the socket isn't inited and should squack
    }
    p.m_pollstate = V1Poll.PS_COMPLETE;
  }
Example #8
0
  int store(BytecodeBuffer b, int start, int end) {
    ByteArray a = wrappers.isEmpty() ? null : (ByteArray) wrappers.pop();

    if (a == null) {
      a = newByteArray();
    }

    a.clear();
    a.b = b;
    a.start = start;
    a.end = end;
    a.init();

    Integer index = IntegerPool.getNumber(map.size() + 1);
    map.put(a, index);

    return index.intValue();
  }
Example #9
0
  // generate operators names table with name length. assign offset for each record
  public static void genenerateOperatorsNamesTable() throws Exception {
    // operatorsNamesBytes
    HashMap hashNames = new HashMap();
    String name;

    for (int i = 0; i < arraySortedRecords.length; i++) {
      name = arraySortedRecords[i].operator_name;

      if (hashNames.containsKey(name)) {
        Integer offset = (Integer) hashNames.get(name);
        arraySortedRecords[i].operator_name_offset = offset.intValue();
      } else {

        byte[] nameByteArr = name.getBytes();
        // since operatorsNamesBytes.length are always even...
        int half_offset = operatorsNamesBytes.length() / 2;
        Validator.validateOperatorNameOffset(half_offset); // validate half_offset
        arraySortedRecords[i].operator_name_offset = half_offset;

        int nameLength =
            nameByteArr.length + 1; // length of name  + one byte to present this length.
        operatorsNamesBytes.addByte((byte) nameLength);
        operatorsNamesBytes.addBytes(nameByteArr);
        if ((operatorsNamesBytes.length() % 2) > 0) {
          // add one dummy byte to make it even
          operatorsNamesBytes.addByte((byte) 0);
        }
        hashNames.put(name, new Integer(half_offset));
      }
    }

    // create operators Names Table
    operatorsNamesTable = new BlockTable(operatorsNamesBytes.length());
    operatorsNamesTable.appendData(operatorsNamesBytes.getBytes());

    Validator.validateOperatorNamesTableSize(operatorsNamesTable.length);
  }
Example #10
0
  private V1NamePoll makeCompletedNamePoll(int numAgree, int numDisagree, int numDissenting)
      throws Exception {
    V1NamePoll np = null;
    V1LcapMessage agree_msg = null;
    V1LcapMessage disagree_msg1 = null;
    V1LcapMessage disagree_msg2 = null;

    Plugin plugin = testau.getPlugin();
    PollSpec spec = new MockPollSpec(testau, rootV1urls[0], null, null, Poll.V1_NAME_POLL);
    ((MockCachedUrlSet) spec.getCachedUrlSet()).setHasContent(false);
    V1LcapMessage poll_msg =
        V1LcapMessage.makeRequestMsg(
            spec,
            null,
            ByteArray.makeRandomBytes(20),
            ByteArray.makeRandomBytes(20),
            V1LcapMessage.NAME_POLL_REQ,
            testduration,
            testID);

    // make our poll
    np =
        (V1NamePoll)
            new V1NamePoll(
                spec,
                pollmanager,
                poll_msg.getOriginatorId(),
                poll_msg.getChallenge(),
                poll_msg.getDuration(),
                poll_msg.getHashAlgorithm());
    np.setMessage(poll_msg);

    // generate agree vote msg
    agree_msg =
        V1LcapMessage.makeReplyMsg(
            poll_msg,
            ByteArray.makeRandomBytes(20),
            poll_msg.getVerifier(),
            agree_entries,
            V1LcapMessage.NAME_POLL_REP,
            testduration,
            testID);

    // generate a disagree vote msg
    disagree_msg1 =
        V1LcapMessage.makeReplyMsg(
            poll_msg,
            ByteArray.makeRandomBytes(20),
            ByteArray.makeRandomBytes(20),
            disagree_entries,
            V1LcapMessage.NAME_POLL_REP,
            testduration,
            testID1);
    // generate a losing disagree vote msg
    disagree_msg2 =
        V1LcapMessage.makeReplyMsg(
            poll_msg,
            ByteArray.makeRandomBytes(20),
            ByteArray.makeRandomBytes(20),
            dissenting_entries,
            V1LcapMessage.NAME_POLL_REP,
            testduration,
            testID1);

    // add our vote
    V1LcapMessage msg = (V1LcapMessage) (np.getMessage());
    PeerIdentity id = msg.getOriginatorId();
    np.m_tally.addVote(np.makeNameVote(msg, true), id, true);

    // add the agree votes
    id = agree_msg.getOriginatorId();
    for (int i = 0; i < numAgree; i++) {
      np.m_tally.addVote(np.makeNameVote(agree_msg, true), id, false);
    }

    // add the disagree votes
    id = disagree_msg1.getOriginatorId();
    for (int i = 0; i < numDisagree; i++) {
      np.m_tally.addVote(np.makeNameVote(disagree_msg1, false), id, false);
    }

    // add dissenting disagree vote
    id = disagree_msg2.getOriginatorId();
    for (int i = 0; i < numDissenting; i++) {
      np.m_tally.addVote(np.makeNameVote(disagree_msg2, false), id, false);
    }
    np.m_pollstate = V1Poll.PS_COMPLETE;
    np.m_tally.tallyVotes();
    return np;
  }
Example #11
0
  private static PeakData<? extends Peak> parsePeakData(Node parent) throws XmlParserException {
    // get the attributes
    Node typeattribute = parent.getAttributes().getNamedItem(PeakMLWriter.TYPE);
    if (typeattribute == null) throw new XmlParserException("Failed to locate a type attribute.");
    Node sizeattribute = parent.getAttributes().getNamedItem(PeakMLWriter.SIZE);
    if (sizeattribute == null) throw new XmlParserException("Failed to locate a size attribute.");

    int size = Integer.parseInt(sizeattribute.getNodeValue());
    String type = typeattribute.getNodeValue();

    // create the arrays
    int scanids[] = null;
    int patternids[] = null;
    int measurementids[] = null;
    double masses[] = null;
    double intensities[] = null;
    double retentiontimes[] = null;

    // retrieve all the data
    NodeList nodes = parent.getChildNodes();
    for (int nodeid = 0; nodeid < nodes.getLength(); ++nodeid) {
      Node node = nodes.item(nodeid);
      if (node.getNodeType() != Node.ELEMENT_NODE) continue;

      Element element = (Element) node;
      if (element.getTagName().equals("scanids"))
        scanids =
            ByteArray.toIntArray(
                Base64.decode(element.getTextContent()), ByteArray.ENDIAN_LITTLE, 32);
      else if (element.getTagName().equals("patternids"))
        patternids =
            ByteArray.toIntArray(
                Base64.decode(element.getTextContent()), ByteArray.ENDIAN_LITTLE, 32);
      else if (element.getTagName().equals("measurementids"))
        measurementids =
            ByteArray.toIntArray(
                Base64.decode(element.getTextContent()), ByteArray.ENDIAN_LITTLE, 32);
      else if (element.getTagName().equals("masses"))
        masses =
            ByteArray.toDoubleArray(
                Base64.decode(element.getTextContent()), ByteArray.ENDIAN_LITTLE, 32);
      else if (element.getTagName().equals("intensities"))
        intensities =
            ByteArray.toDoubleArray(
                Base64.decode(element.getTextContent()), ByteArray.ENDIAN_LITTLE, 32);
      else if (element.getTagName().equals("retentiontimes"))
        retentiontimes =
            ByteArray.toDoubleArray(
                Base64.decode(element.getTextContent()), ByteArray.ENDIAN_LITTLE, 32);
    }

    // create the PeakData instance
    if (type.equals("centroid"))
      return new PeakData<Centroid>(
          Centroid.factory,
          size,
          scanids,
          patternids,
          measurementids,
          masses,
          intensities,
          retentiontimes);
    return null;
  }
 private byte[] fromHex(String hex) {
   return ByteArray.fromHexString(hex);
 }
Example #13
0
/** JUnitTest case for class: org.lockss.protocol.Message */
public class TestV3LcapMessage extends LockssTestCase {

  private String m_url = "http://www.example.com";

  private String m_archivalID = "TestAU_1.0";
  private PeerIdentity m_testID;
  private V3LcapMessage m_testMsg;
  private List m_testVoteBlocks;
  private MockPollManager mPollMgr;

  private MockLockssDaemon theDaemon;

  private File tempDir;

  private byte[] m_testBytes =
      new byte[] {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
        1, 2, 3, 4, 5, 6, 7, 8, 9, 0
      };

  private byte[] m_repairData = ByteArray.makeRandomBytes(1000);
  private CIProperties m_repairProps = null;

  public void setUp() throws Exception {
    super.setUp();
    theDaemon = getMockLockssDaemon();
    tempDir = getTempDir();
    String tempDirPath = tempDir.getAbsolutePath();
    System.setProperty("java.io.tmpdir", tempDirPath);

    Properties p = new Properties();
    p.setProperty(IdentityManager.PARAM_IDDB_DIR, tempDirPath + "iddb");
    p.setProperty(ConfigManager.PARAM_PLATFORM_DISK_SPACE_LIST, tempDirPath);
    p.setProperty(IdentityManager.PARAM_LOCAL_IP, "127.0.0.1");
    p.setProperty(V3LcapMessage.PARAM_REPAIR_DATA_THRESHOLD, "4096");
    ConfigurationUtil.setCurrentConfigFromProps(p);
    IdentityManager idmgr = theDaemon.getIdentityManager();
    idmgr.startService();
    mPollMgr = new MockPollManager();
    theDaemon.setPollManager(mPollMgr);
    try {
      m_testID = idmgr.stringToPeerIdentity("127.0.0.1");
    } catch (IOException ex) {
      fail("can't open test host 127.0.0.1: " + ex);
    }
    m_repairProps = new CIProperties();
    m_repairProps.setProperty("key1", "val1");
    m_repairProps.setProperty("key2", "val2");
    m_repairProps.setProperty("key3", "val3");

    m_testVoteBlocks = V3TestUtils.makeVoteBlockList(10);
    m_testMsg = this.makeTestVoteMessage(m_testVoteBlocks);
  }

  public void testNoOpMessageCreation() throws Exception {
    // Without voterNonce2
    V3LcapMessage noopMsg =
        V3LcapMessage.makeNoOpMsg(m_testID, m_testBytes, m_testBytes, theDaemon);
    // With voterNonce2
    V3LcapMessage noopMsg2 =
        V3LcapMessage.makeNoOpMsg(m_testID, m_testBytes, m_testBytes, m_testBytes, theDaemon);

    // now check the fields we expect to be valid
    assertEquals(V3LcapMessage.MSG_NO_OP, noopMsg.getOpcode());
    assertTrue(m_testID == noopMsg.getOriginatorId());
    assertEquals(m_testBytes, noopMsg.getPollerNonce());
    assertEquals(m_testBytes, noopMsg.getVoterNonce());
    assertEquals(null, noopMsg.getVoterNonce2());
    assertEquals(null, noopMsg.getVoteBlocks());
    assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH, noopMsg.getEstimatedEncodedLength());

    // Same for msg with voterNonce2
    assertEquals(V3LcapMessage.MSG_NO_OP, noopMsg2.getOpcode());
    assertTrue(m_testID == noopMsg2.getOriginatorId());
    assertEquals(m_testBytes, noopMsg2.getPollerNonce());
    assertEquals(m_testBytes, noopMsg2.getVoterNonce());
    assertEquals(m_testBytes, noopMsg2.getVoterNonce2());
    assertEquals(null, noopMsg2.getVoteBlocks());
    assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH, noopMsg2.getEstimatedEncodedLength());
  }

  public void testRandomNoOpMessageCreation() throws Exception {
    V3LcapMessage noopMsg1 = V3LcapMessage.makeNoOpMsg(m_testID, theDaemon);
    V3LcapMessage noopMsg2 = V3LcapMessage.makeNoOpMsg(m_testID, theDaemon);

    // now check the fields we expect to be valid
    assertEquals(V3LcapMessage.MSG_NO_OP, noopMsg1.getOpcode());
    assertEquals(V3LcapMessage.MSG_NO_OP, noopMsg2.getOpcode());
    assertTrue(noopMsg1.getOriginatorId() == m_testID);
    assertTrue(noopMsg1.getOriginatorId() == noopMsg2.getOriginatorId());
    assertFalse(noopMsg1.getPollerNonce() == noopMsg2.getPollerNonce());
    assertFalse(noopMsg1.getVoterNonce() == noopMsg2.getVoterNonce());
    assertEquals(null, noopMsg1.getVoterNonce2());
    assertEquals(null, noopMsg2.getVoterNonce2());
    assertEquals(null, noopMsg1.getVoteBlocks());
    assertEquals(null, noopMsg2.getVoteBlocks());
  }

  public void testNoOpMessageToString() throws IOException {
    V3LcapMessage noopMsg =
        V3LcapMessage.makeNoOpMsg(m_testID, m_testBytes, m_testBytes, theDaemon);
    String expectedResult = "[V3LcapMessage: from " + m_testID.toString() + ", NoOp]";
    assertEquals(expectedResult, noopMsg.toString());
  }

  public void testTestMessageToString() throws IOException {
    String expectedResult =
        "[V3LcapMessage: from "
            + m_testID.toString()
            + ", Vote AUID: TestAU_1.0 "
            + "Key:key "
            + "PN:AQIDBAUGBwgJAAECAwQFBgcICQA= "
            + "VN:AQIDBAUGBwgJAAECAwQFBgcICQA= "
            + "B:10 ver 3 rev 5]";
    assertEquals(expectedResult, m_testMsg.toString());
  }

  public void getGroup() throws Exception {
    m_testMsg.setGroups(null);
    assertNull(m_testMsg.getGroups());
    assertNull(m_testMsg.getGroupList());
    m_testMsg.setGroups("foo");
    assertEquals("foo", m_testMsg.getGroups());
    assertEquals(ListUtil.list("foo"), m_testMsg.getGroupList());
    m_testMsg.setGroups("foo;bar");
    assertEquals("foo;bar", m_testMsg.getGroups());
    assertEquals(ListUtil.list("foo", "bar"), m_testMsg.getGroupList());
    m_testMsg.setGroups("foo;bar;baz");
    assertEquals("foo;bar;baz", m_testMsg.getGroups());
    assertEquals(ListUtil.list("foo", "bar", "baz"), m_testMsg.getGroupList());
  }

  public void testNoOpEncoding() throws Exception {
    V3LcapMessage noopMsg =
        V3LcapMessage.makeNoOpMsg(m_testID, m_testBytes, m_testBytes, theDaemon);
    InputStream fromMsg = noopMsg.getInputStream();
    V3LcapMessage msg = new V3LcapMessage(fromMsg, tempDir, theDaemon);
    // now test to see if we got back what we started with
    assertTrue(m_testID == msg.getOriginatorId());
    assertEquals(V3LcapMessage.MSG_NO_OP, msg.getOpcode());
    assertEquals(m_testBytes, msg.getPollerNonce());
    assertEquals(m_testBytes, msg.getVoterNonce());
    assertEquals(null, msg.getVoterNonce2());
  }

  public void testMemoryRepairMessage() throws Exception {
    int len = 1024;
    byte[] repairData = ByteArray.makeRandomBytes(len);
    V3LcapMessage src = makeRepairMessage(repairData);
    assertEquals(len, src.getRepairDataLength());
    assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH + len, src.getEstimatedEncodedLength());
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertEquals(len, copy.getRepairDataLength());
    assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH + len, src.getEstimatedEncodedLength());
    InputStream in = copy.getRepairDataInputStream();
    assertTrue(in + "", in instanceof ByteArrayInputStream);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    StreamUtil.copy(in, out);
    byte[] repairCopy = out.toByteArray();
    assertEquals(repairData, repairCopy);
    // ensure that repeated delete doesn't cause error
    copy.delete();
    copy.delete();
  }

  public void testDiskRepairMessage() throws Exception {
    int len = 100 * 1024;
    byte[] repairData = ByteArray.makeRandomBytes(len);
    V3LcapMessage src = makeRepairMessage(repairData);
    assertEquals(len, src.getRepairDataLength());
    assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH + len, src.getEstimatedEncodedLength());
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertEquals(len, copy.getRepairDataLength());
    assertEquals(V3LcapMessage.EST_ENCODED_HEADER_LENGTH + len, src.getEstimatedEncodedLength());
    InputStream in = copy.getRepairDataInputStream();
    assertTrue(in + "", in instanceof FileInputStream);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    StreamUtil.copy(in, out);
    byte[] repairCopy = out.toByteArray();
    assertEquals(repairData, repairCopy);
    // ensure that repeated delete doesn't cause error
    copy.delete();
    copy.delete();
  }

  public void testPollDuration() throws Exception {
    TimeBase.setSimulated(TimeBase.nowMs());
    V3LcapMessage src = this.makePollMessage(6 * Constants.WEEK);
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertEquals(6 * Constants.WEEK, copy.getDuration());
  }

  public void testNullPollNak() throws Exception {
    V3LcapMessage src = this.makePollAckMessage(null);
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertNull(src.getNak());
    assertNull(copy.getNak());
  }

  public void testNonNullPollNak1() throws Exception {
    V3LcapMessage src = this.makePollAckMessage(V3LcapMessage.PollNak.NAK_GROUP_MISMATCH);
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertNotNull(src.getNak());
    assertNotNull(copy.getNak());
    assertEquals(V3LcapMessage.PollNak.NAK_GROUP_MISMATCH, src.getNak());
    assertEquals(V3LcapMessage.PollNak.NAK_GROUP_MISMATCH, copy.getNak());
  }

  public void testNonNullPollNak2() throws Exception {
    V3LcapMessage src = this.makePollAckMessage(V3LcapMessage.PollNak.NAK_NO_TIME);
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertNotNull(src.getNak());
    assertNotNull(copy.getNak());
    assertEquals(V3LcapMessage.PollNak.NAK_NO_TIME, src.getNak());
    assertEquals(V3LcapMessage.PollNak.NAK_NO_TIME, copy.getNak());
  }

  public void testUnknownPollNak() throws Exception {
    MyV3LcapMessage src = makePollAckMessage(V3LcapMessage.PollNak.NAK_NO_TIME);
    src.setTestNak("KNACKERED");
    InputStream srcStream = src.getInputStream();
    V3LcapMessage copy = new V3LcapMessage(srcStream, tempDir, theDaemon);
    assertEqualMessages(src, copy);
    assertNotNull(src.getNak());
    assertNotNull(copy.getNak());
    assertEquals(V3LcapMessage.PollNak.NAK_NO_TIME, src.getNak());
    assertEquals(V3LcapMessage.PollNak.NAK_UNKNOWN, copy.getNak());
  }

  public void testRequestMessageCreation() throws Exception {
    V3LcapMessage reqMsg =
        new V3LcapMessage(
            "ArchivalID_2",
            "key",
            "Plug42",
            m_testBytes,
            m_testBytes,
            V3LcapMessage.MSG_REPAIR_REQ,
            987654321,
            m_testID,
            tempDir,
            theDaemon);
    reqMsg.setTargetUrl("http://foo.com/");

    for (Iterator ix = m_testVoteBlocks.iterator(); ix.hasNext(); ) {
      reqMsg.addVoteBlock((VoteBlock) ix.next());
    }

    assertEquals(3, reqMsg.getProtocolVersion());
    assertEquals("Plug42", reqMsg.getPluginVersion());
    assertTrue(m_testID == reqMsg.getOriginatorId());
    assertEquals(V3LcapMessage.MSG_REPAIR_REQ, reqMsg.getOpcode());
    assertEquals("ArchivalID_2", reqMsg.getArchivalId());
    assertEquals("http://foo.com/", reqMsg.getTargetUrl());
    assertEquals(m_testBytes, reqMsg.getPollerNonce());
    assertEquals(m_testBytes, reqMsg.getVoterNonce());
    assertEquals(null, reqMsg.getVoterNonce2());
    List aBlocks = new ArrayList();
    List bBlocks = new ArrayList();
    for (VoteBlocksIterator iter = m_testMsg.getVoteBlockIterator(); iter.hasNext(); ) {
      aBlocks.add(iter.next());
    }
    for (VoteBlocksIterator iter = reqMsg.getVoteBlockIterator(); iter.hasNext(); ) {
      bBlocks.add(iter.next());
    }
    assertEquals(aBlocks, bBlocks);

    // Actual size of test vote blocks is unpredictable
    assertTrue(reqMsg.getEstimatedEncodedLength() > V3LcapMessage.EST_ENCODED_HEADER_LENGTH);
  }

  public void testDiskBasedStreamEncodingTest() throws Exception {
    // Make a list of vote blocks large enough to trigger on-disk
    // vote message creation.
    List testVoteBlocks = V3TestUtils.makeVoteBlockList(21);
    V3LcapMessage testMsg = makeTestVoteMessage(testVoteBlocks);
    assertTrue(testMsg.m_voteBlocks instanceof DiskVoteBlocks);
    // Encode the test message.
    InputStream is = testMsg.getInputStream();
    V3LcapMessage decodedMsg = new V3LcapMessage(is, tempDir, theDaemon);
    // Ensure that the decoded message matches the test message.
    assertEqualMessages(testMsg, decodedMsg);
  }

  private void assertEqualMessages(V3LcapMessage a, V3LcapMessage b) throws Exception {
    assertTrue(a.getOriginatorId() == b.getOriginatorId());
    assertEquals(a.getOpcode(), b.getOpcode());
    assertEquals(a.getTargetUrl(), b.getTargetUrl());
    assertEquals(a.getArchivalId(), b.getArchivalId());
    assertEquals(a.getProtocolVersion(), b.getProtocolVersion());
    assertEquals(a.getPollerNonce(), b.getPollerNonce());
    assertEquals(a.getVoterNonce(), b.getVoterNonce());
    assertEquals(a.getVoterNonce2(), b.getVoterNonce2());
    assertEquals(a.getPluginVersion(), b.getPluginVersion());
    assertEquals(a.getHashAlgorithm(), b.getHashAlgorithm());
    assertEquals(a.isVoteComplete(), b.isVoteComplete());
    assertEquals(a.getRepairDataLength(), b.getRepairDataLength());
    assertEquals(a.getLastVoteBlockURL(), b.getLastVoteBlockURL());
    assertIsomorphic(a.getNominees(), b.getNominees());
    List aBlocks = new ArrayList();
    List bBlocks = new ArrayList();
    for (VoteBlocksIterator iter = a.getVoteBlockIterator(); iter.hasNext(); ) {
      aBlocks.add(iter.next());
    }
    for (VoteBlocksIterator iter = b.getVoteBlockIterator(); iter.hasNext(); ) {
      bBlocks.add(iter.next());
    }
    assertTrue(aBlocks.equals(bBlocks));

    //  TODO: Figure out how to test time.

  }

  private V3LcapMessage makePollMessage(long duration) {
    V3LcapMessage msg =
        new V3LcapMessage(
            "ArchivalID_2",
            "key",
            "Plug42",
            m_testBytes,
            m_testBytes,
            V3LcapMessage.MSG_POLL,
            TimeBase.nowMs() + duration,
            m_testID,
            tempDir,
            theDaemon);
    return msg;
  }

  private MyV3LcapMessage makePollAckMessage(V3LcapMessage.PollNak nak) {
    MyV3LcapMessage msg =
        new MyV3LcapMessage(
            "ArchivalID_2",
            "key",
            "Plug42",
            m_testBytes,
            m_testBytes,
            V3LcapMessage.MSG_POLL_ACK,
            987654321,
            m_testID,
            tempDir,
            theDaemon);
    if (nak != null) {
      msg.setNak(nak);
    }

    return msg;
  }

  private V3LcapMessage makeRepairMessage(byte[] repairData) {
    V3LcapMessage msg =
        new V3LcapMessage(
            "ArchivalID_2",
            "key",
            "Plug42",
            m_testBytes,
            m_testBytes,
            V3LcapMessage.MSG_REPAIR_REP,
            987654321,
            m_testID,
            tempDir,
            theDaemon);
    msg.setHashAlgorithm(LcapMessage.getDefaultHashAlgorithm());
    msg.setTargetUrl(m_url);
    msg.setArchivalId(m_archivalID);
    msg.setPluginVersion("PlugVer42");
    msg.setRepairDataLength(repairData.length);
    msg.setRepairProps(m_repairProps);
    msg.setInputStream(new ByteArrayInputStream(repairData));
    return msg;
  }

  private V3LcapMessage makeTestVoteMessage(Collection voteBlocks) throws IOException {
    mPollMgr.setStateDir("key", tempDir);
    V3LcapMessage msg =
        new V3LcapMessage(
            "ArchivalID_2",
            "key",
            "Plug42",
            m_testBytes,
            m_testBytes,
            V3LcapMessage.MSG_VOTE,
            987654321,
            m_testID,
            tempDir,
            theDaemon);

    // Set msg vote blocks.
    for (Iterator ix = voteBlocks.iterator(); ix.hasNext(); ) {
      msg.addVoteBlock((VoteBlock) ix.next());
    }

    msg.setHashAlgorithm(LcapMessage.getDefaultHashAlgorithm());
    msg.setArchivalId(m_archivalID);
    msg.setPluginVersion("PlugVer42");
    return msg;
  }

  static class MyV3LcapMessage extends V3LcapMessage {
    String testNak;

    public MyV3LcapMessage(File messageDir, LockssApp daemon) {
      super(messageDir, daemon);
    }

    public MyV3LcapMessage(
        String auId,
        String pollKey,
        String pluginVersion,
        byte[] pollerNonce,
        byte[] voterNonce,
        int opcode,
        long deadline,
        PeerIdentity origin,
        File messageDir,
        LockssApp daemon) {
      super(
          auId,
          pollKey,
          pluginVersion,
          pollerNonce,
          voterNonce,
          opcode,
          deadline,
          origin,
          messageDir,
          daemon);
    }

    public MyV3LcapMessage(
        String auId,
        String pollKey,
        String pluginVersion,
        byte[] pollerNonce,
        byte[] voterNonce,
        byte[] voterNonce2,
        int opcode,
        long deadline,
        PeerIdentity origin,
        File messageDir,
        LockssApp daemon) {
      super(
          auId,
          pollKey,
          pluginVersion,
          pollerNonce,
          voterNonce,
          voterNonce2,
          opcode,
          deadline,
          origin,
          messageDir,
          daemon);
    }

    public MyV3LcapMessage(byte[] encodedBytes, File messageDir, LockssApp daemon)
        throws IOException {
      super(encodedBytes, messageDir, daemon);
    }

    public MyV3LcapMessage(InputStream inputStream, File messageDir, LockssApp daemon)
        throws IOException {
      super(inputStream, messageDir, daemon);
    }

    void setTestNak(String nakName) {
      testNak = nakName;
    }

    public void storeProps() throws IOException {
      super.storeProps();
      if (testNak != null) {
        m_props.setProperty("nak", testNak);
      }
    }
  }
}