@Test
  public void sendWriteTestWithBadId() throws IOException, MessageFormatException {
    // add header,system metadata, user metadata and data to the buffers
    ByteBuffer buf1 = ByteBuffer.allocate(1010);
    // fill header
    buf1.putShort((short) 1);                    // version
    buf1.putLong(950);                          // total size
    // put relative offsets
    buf1.putInt(60);                           // blob property relative offset
    buf1.putInt(-1);                           // delete relative offset
    buf1.putInt(81);                           // user metadata relative offset
    buf1.putInt(191);                          // data relative offset
    CRC32 crc = new CRC32();
    crc.update(buf1.array(), 0, buf1.position());
    buf1.putLong(crc.getValue());                          // crc
    String id = new String("012345678910123456789012");     // blob id
    buf1.putShort((short) id.length());
    buf1.put(id.getBytes());

    buf1.putShort((short) 1); // blob property version
    String attribute1 = "ttl";
    String attribute2 = "del";
    buf1.put(attribute1.getBytes()); // ttl name
    buf1.putLong(12345);             // ttl value
    buf1.put(attribute2.getBytes()); // delete name
    byte b = 1;
    buf1.put(b);      // delete flag
    buf1.putInt(456); //crc

    buf1.putShort((short) 1); // user metadata version
    buf1.putInt(100);
    byte[] usermetadata = new byte[100];
    new Random().nextBytes(usermetadata);
    buf1.put(usermetadata);
    buf1.putInt(123);

    buf1.putShort((short) 0); // blob version
    buf1.putLong(805);       // blob size
    byte[] data = new byte[805];         // blob
    new Random().nextBytes(data);
    buf1.put(data);
    buf1.putInt(123);                    // blob crc
    buf1.flip();

    ArrayList<ByteBuffer> listbuf = new ArrayList<ByteBuffer>();
    listbuf.add(buf1);
    ArrayList<StoreKey> storeKeys = new ArrayList<StoreKey>();
    storeKeys.add(new MockId("012345678910123223233456789012"));
    MessageReadSet readSet = new MockMessageReadSet(listbuf, storeKeys);

    MetricRegistry registry = new MetricRegistry();
    MessageFormatMetrics metrics = new MessageFormatMetrics(registry);
    // get all
    MessageFormatSend send = new MessageFormatSend(readSet, MessageFormatFlags.All, metrics, new MockIdFactory());
    Assert.assertEquals(send.sizeInBytes(), 1010);
    ByteBuffer bufresult = ByteBuffer.allocate(1010);
    WritableByteChannel channel1 = Channels.newChannel(new ByteBufferOutputStream(bufresult));
    while (!send.isSendComplete()) {
      send.writeTo(channel1);
    }
    Assert.assertArrayEquals(buf1.array(), bufresult.array());
    try {
      // get blob
      MessageFormatSend send1 = new MessageFormatSend(readSet, MessageFormatFlags.Blob, metrics, new MockIdFactory());
      Assert.fail("Exception is expected");
    } catch (MessageFormatException e) {
      Assert.assertTrue(e.getErrorCode() == MessageFormatErrorCodes.StoreKeyIdMisMatch);
    }
  }
Helper method to test multiple messages in a single Send involving different combinations of header format
versions, put formats and encryption keys.
@param blob the array of blob records for the messages.
@param userMetadata the array of userMetadata for the messages.
@param storeKeys the array of store keys for the messages.
@param encryptionKeys the array of encryption keys for the messages.
@param putFormats the array of Put Format class names to use to create the message streams.
@param headerVersions the array of Message Header versions to use for the messages.
ambry-messageformat/src/test/java/com/github/ambry/messageformat/MessageFormatSendTest.java