| /* |
| * 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.cassandra.service; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| |
| import org.junit.*; |
| |
| import org.apache.cassandra.SchemaLoader; |
| import org.apache.cassandra.config.DatabaseDescriptor; |
| import org.apache.cassandra.db.*; |
| import org.apache.cassandra.exceptions.StartupException; |
| import org.apache.cassandra.io.util.FileUtils; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| public class StartupChecksTest |
| { |
| public static final String INVALID_LEGACY_SSTABLE_ROOT_PROP = "invalid-legacy-sstable-root"; |
| StartupChecks startupChecks; |
| Path sstableDir; |
| |
| @BeforeClass |
| public static void setupServer() |
| { |
| SchemaLoader.prepareServer(); |
| } |
| |
| @Before |
| public void setup() throws IOException |
| { |
| for (ColumnFamilyStore cfs : Keyspace.open(SystemKeyspace.NAME).getColumnFamilyStores()) |
| cfs.clearUnsafe(); |
| for (File dataDir : Directories.getKSChildDirectories(SystemKeyspace.NAME)) |
| FileUtils.deleteRecursive(dataDir); |
| |
| File dataDir = new File(DatabaseDescriptor.getAllDataFileLocations()[0]); |
| sstableDir = Paths.get(dataDir.getAbsolutePath(), "Keyspace1", "Standard1"); |
| Files.createDirectories(sstableDir); |
| |
| startupChecks = new StartupChecks(); |
| } |
| |
| @After |
| public void tearDown() throws IOException |
| { |
| FileUtils.deleteRecursive(sstableDir.toFile()); |
| } |
| |
| @Test |
| public void failStartupIfInvalidSSTablesFound() throws Exception |
| { |
| startupChecks = startupChecks.withTest(StartupChecks.checkSSTablesFormat); |
| |
| copyInvalidLegacySSTables(sstableDir); |
| |
| verifyFailure(startupChecks, "Detected unreadable sstables"); |
| |
| // we should ignore invalid sstables in a snapshots directory |
| FileUtils.deleteRecursive(sstableDir.toFile()); |
| Path snapshotDir = sstableDir.resolve("snapshots"); |
| Files.createDirectories(snapshotDir); |
| copyInvalidLegacySSTables(snapshotDir); startupChecks.verify(); |
| |
| // and in a backups directory |
| FileUtils.deleteRecursive(sstableDir.toFile()); |
| Path backupDir = sstableDir.resolve("backups"); |
| Files.createDirectories(backupDir); |
| copyInvalidLegacySSTables(backupDir); |
| startupChecks.verify(); |
| } |
| |
| @Test |
| public void compatibilityCheckIgnoresNonDbFiles() throws Exception |
| { |
| startupChecks = startupChecks.withTest(StartupChecks.checkSSTablesFormat); |
| |
| copyLegacyNonSSTableFiles(sstableDir); |
| assertFalse(sstableDir.toFile().listFiles().length == 0); |
| |
| startupChecks.verify(); |
| } |
| |
| @Test |
| public void maxMapCountCheck() throws Exception |
| { |
| startupChecks = startupChecks.withTest(StartupChecks.checkMaxMapCount); |
| startupChecks.verify(); |
| } |
| |
| private void copyLegacyNonSSTableFiles(Path targetDir) throws IOException |
| { |
| |
| Path legacySSTableRoot = Paths.get(System.getProperty(INVALID_LEGACY_SSTABLE_ROOT_PROP), |
| "Keyspace1", |
| "Standard1"); |
| for (String filename : new String[]{"Keyspace1-Standard1-ic-0-TOC.txt", |
| "Keyspace1-Standard1-ic-0-Digest.sha1", |
| "legacyleveled.json"}) |
| Files.copy(Paths.get(legacySSTableRoot.toString(), filename), targetDir.resolve(filename)); |
| } |
| |
| private void copyInvalidLegacySSTables(Path targetDir) throws IOException |
| { |
| File legacySSTableRoot = Paths.get(System.getProperty(INVALID_LEGACY_SSTABLE_ROOT_PROP), |
| "Keyspace1", |
| "Standard1").toFile(); |
| for (File f : legacySSTableRoot.listFiles()) |
| Files.copy(f.toPath(), targetDir.resolve(f.getName())); |
| |
| } |
| |
| private void verifyFailure(StartupChecks tests, String message) |
| { |
| try |
| { |
| tests.verify(); |
| fail("Expected a startup exception but none was thrown"); |
| } |
| catch (StartupException e) |
| { |
| assertTrue(e.getMessage().contains(message)); |
| } |
| } |
| } |