/*
* Copyright 2014-2017 Real Logic Ltd.
*
* Licensed 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 io.aeron.archiver;
import io.aeron.archiver.codecs.RecordingDescriptorDecoder;
import org.agrona.*;
import org.agrona.concurrent.UnsafeBuffer;
import org.junit.*;
import java.io.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.Mockito.mock;
public class CatalogTest
{
public static final int SEGMENT_FILE_SIZE = 128 * 1024 * 1024;
static final UnsafeBuffer BUFFER = new UnsafeBuffer(
BufferUtil.allocateDirectAligned(Catalog.RECORD_LENGTH, 64));
static final RecordingDescriptorDecoder DECODER = new RecordingDescriptorDecoder();
static long recordingAId;
static long recordingBId;
static long recordingCId;
static RecordingSession mockSession = mock(RecordingSession.class);
private static File archiveDir;
@BeforeClass
public static void setup() throws Exception
{
DECODER.wrap(
BUFFER,
Catalog.CATALOG_FRAME_LENGTH,
RecordingDescriptorDecoder.BLOCK_LENGTH,
RecordingDescriptorDecoder.SCHEMA_VERSION);
archiveDir = TestUtil.makeTempDir();
try (Catalog catalog = new Catalog(archiveDir))
{
recordingAId = catalog.addNewRecording("sourceA", 6, "channelG", 1, 4096, 1024, 0, 0L,
mockSession, SEGMENT_FILE_SIZE);
recordingBId = catalog.addNewRecording("sourceV", 7, "channelH", 2, 4096, 1024, 0, 0L,
mockSession, SEGMENT_FILE_SIZE);
recordingCId = catalog.addNewRecording("sourceB", 8, "channelK", 3, 4096, 1024, 0, 0L,
mockSession, SEGMENT_FILE_SIZE);
catalog.removeRecordingSession(recordingAId);
catalog.removeRecordingSession(recordingBId);
catalog.removeRecordingSession(recordingCId);
}
}
@AfterClass
public static void teardown()
{
IoUtil.delete(archiveDir, false);
}
@Test
public void shouldReloadExistingIndex() throws Exception
{
try (Catalog catalog = new Catalog(archiveDir))
{
verifyRecordingForId(catalog, recordingAId, "sourceA", 6, "channelG", 1);
verifyRecordingForId(catalog, recordingBId, "sourceV", 7, "channelH", 2);
verifyRecordingForId(catalog, recordingCId, "sourceB", 8, "channelK", 3);
}
}
private void verifyRecordingForId(
final Catalog catalog,
final long id,
final String source,
final int sessionId,
final String channel,
final int streamId)
throws IOException
{
BUFFER.byteBuffer().clear();
catalog.readDescriptor(id, BUFFER.byteBuffer());
DECODER.limit(Catalog.CATALOG_FRAME_LENGTH + RecordingDescriptorDecoder.BLOCK_LENGTH);
assertEquals(id, DECODER.recordingId());
assertEquals(sessionId, DECODER.sessionId());
assertEquals(streamId, DECODER.streamId());
assertEquals(source, DECODER.source());
assertEquals(channel, DECODER.channel());
}
@Test
public void shouldAppendToExistingIndex() throws Exception
{
final long newRecordingId;
try (Catalog catalog = new Catalog(archiveDir))
{
newRecordingId = catalog.addNewRecording(
"sourceN", 9, "channelJ", 4, 4096, 1024, 0,
0L, mockSession, SEGMENT_FILE_SIZE);
catalog.removeRecordingSession(newRecordingId);
}
try (Catalog catalog = new Catalog(archiveDir))
{
verifyRecordingForId(catalog, recordingAId, "sourceA", 6, "channelG", 1);
verifyRecordingForId(catalog, newRecordingId, "sourceN", 9, "channelJ", 4);
}
}
@Test
public void shouldAllowMultipleInstancesForSameStream() throws Exception
{
final long newRecordingId;
try (Catalog catalog = new Catalog(archiveDir))
{
newRecordingId = catalog.addNewRecording(
"sourceA", 6, "channelG", 1, 4096, 1024, 0,
0L, mockSession, SEGMENT_FILE_SIZE);
catalog.removeRecordingSession(newRecordingId);
assertNotEquals(recordingAId, newRecordingId);
}
}
}