/* * 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); } } }