/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.kafka.common.record;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(value = Parameterized.class)
public class LegacyRecordTest {
private final byte magic;
private final long timestamp;
private final ByteBuffer key;
private final ByteBuffer value;
private final CompressionType compression;
private final TimestampType timestampType;
private final LegacyRecord record;
public LegacyRecordTest(byte magic, long timestamp, byte[] key, byte[] value, CompressionType compression) {
this.magic = magic;
this.timestamp = timestamp;
this.timestampType = TimestampType.CREATE_TIME;
this.key = key == null ? null : ByteBuffer.wrap(key);
this.value = value == null ? null : ByteBuffer.wrap(value);
this.compression = compression;
this.record = LegacyRecord.create(magic, timestamp, key, value, compression, timestampType);
}
@Test
public void testFields() {
assertEquals(compression, record.compressionType());
assertEquals(key != null, record.hasKey());
assertEquals(key, record.key());
if (key != null)
assertEquals(key.limit(), record.keySize());
assertEquals(magic, record.magic());
assertEquals(value, record.value());
if (value != null)
assertEquals(value.limit(), record.valueSize());
if (magic > 0) {
assertEquals(timestamp, record.timestamp());
assertEquals(timestampType, record.timestampType());
} else {
assertEquals(RecordBatch.NO_TIMESTAMP, record.timestamp());
assertEquals(TimestampType.NO_TIMESTAMP_TYPE, record.timestampType());
}
}
@Test
public void testChecksum() {
assertEquals(record.checksum(), record.computeChecksum());
byte attributes = LegacyRecord.computeAttributes(magic, this.compression, TimestampType.CREATE_TIME);
assertEquals(record.checksum(), LegacyRecord.computeChecksum(
magic,
attributes,
this.timestamp,
this.key == null ? null : this.key.array(),
this.value == null ? null : this.value.array()
));
assertTrue(record.isValid());
for (int i = LegacyRecord.CRC_OFFSET + LegacyRecord.CRC_LENGTH; i < record.sizeInBytes(); i++) {
LegacyRecord copy = copyOf(record);
copy.buffer().put(i, (byte) 69);
assertFalse(copy.isValid());
try {
copy.ensureValid();
fail("Should fail the above test.");
} catch (InvalidRecordException e) {
// this is good
}
}
}
private LegacyRecord copyOf(LegacyRecord record) {
ByteBuffer buffer = ByteBuffer.allocate(record.sizeInBytes());
record.buffer().put(buffer);
buffer.rewind();
record.buffer().rewind();
return new LegacyRecord(buffer);
}
@Test
public void testEquality() {
assertEquals(record, copyOf(record));
}
@Parameters
public static Collection<Object[]> data() {
byte[] payload = new byte[1000];
Arrays.fill(payload, (byte) 1);
List<Object[]> values = new ArrayList<>();
for (byte magic : Arrays.asList(RecordBatch.MAGIC_VALUE_V0, RecordBatch.MAGIC_VALUE_V1))
for (long timestamp : Arrays.asList(RecordBatch.NO_TIMESTAMP, 0L, 1L))
for (byte[] key : Arrays.asList(null, "".getBytes(), "key".getBytes(), payload))
for (byte[] value : Arrays.asList(null, "".getBytes(), "value".getBytes(), payload))
for (CompressionType compression : CompressionType.values())
values.add(new Object[] {magic, timestamp, key, value, compression});
return values;
}
}