/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.index.translog;
import org.elasticsearch.index.seqno.SequenceNumbersService;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
/**
* Tests for reading old and new translog files
*/
public class TranslogVersionTests extends ESTestCase {
private void checkFailsToOpen(String file, String expectedMessage) throws IOException {
Path translogFile = getDataPath(file);
assertThat("test file should exist", Files.exists(translogFile), equalTo(true));
try {
openReader(translogFile, 0);
fail("should be able to open an old translog");
} catch (IllegalStateException e) {
assertThat(e.getMessage(), containsString(expectedMessage));
}
}
public void testV0LegacyTranslogVersion() throws Exception {
checkFailsToOpen("/org/elasticsearch/index/translog/translog-v0.binary", "pre-1.4 translog");
}
public void testV1ChecksummedTranslogVersion() throws Exception {
checkFailsToOpen("/org/elasticsearch/index/translog/translog-v1.binary", "pre-2.0 translog");
}
public void testCorruptedTranslogs() throws Exception {
try {
Path translogFile = getDataPath("/org/elasticsearch/index/translog/translog-v1-corrupted-magic.binary");
assertThat("test file should exist", Files.exists(translogFile), equalTo(true));
openReader(translogFile, 0);
fail("should have thrown an exception about the header being corrupt");
} catch (TranslogCorruptedException e) {
assertThat("translog corruption from header: " + e.getMessage(),
e.getMessage().contains("translog looks like version 1 or later, but has corrupted header"), equalTo(true));
}
try {
Path translogFile = getDataPath("/org/elasticsearch/index/translog/translog-invalid-first-byte.binary");
assertThat("test file should exist", Files.exists(translogFile), equalTo(true));
openReader(translogFile, 0);
fail("should have thrown an exception about the header being corrupt");
} catch (TranslogCorruptedException e) {
assertThat("translog corruption from header: " + e.getMessage(),
e.getMessage().contains("Invalid first byte in translog file, got: 1, expected 0x00 or 0x3f"), equalTo(true));
}
checkFailsToOpen("/org/elasticsearch/index/translog/translog-v1-corrupted-body.binary", "pre-2.0 translog");
}
public void testTruncatedTranslog() throws Exception {
checkFailsToOpen("/org/elasticsearch/index/translog/translog-v1-truncated.binary", "pre-2.0 translog");
}
public TranslogReader openReader(final Path path, final long id) throws IOException {
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
final long minSeqNo = SequenceNumbersService.NO_OPS_PERFORMED;
final long maxSeqNo = SequenceNumbersService.NO_OPS_PERFORMED;
final Checkpoint checkpoint =
new Checkpoint(Files.size(path), 1, id, minSeqNo, maxSeqNo, SequenceNumbersService.UNASSIGNED_SEQ_NO);
return TranslogReader.open(channel, path, checkpoint, null);
}
}
}