blob: e9d20705709519097c606f8654a51c03261aaa46 [file] [log] [blame]
/*
* 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.tools;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.cassandra.io.util.File;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.StartupException;
import org.apache.cassandra.io.sstable.LegacySSTableTest;
import org.apache.cassandra.io.sstable.format.SSTableReader;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.tools.ToolRunner.ToolResult;
import org.assertj.core.api.Assertions;
import org.assertj.core.util.Lists;
import static org.junit.Assert.assertEquals;
/*
* SStableUpdater should be run with the server shutdown, but we need to set up a certain env to be able to
* load/swap/drop sstable files under the test's feet. Hence why we need a separate file vs StandaloneUpgraderTest.
*
* Caution: heavy hacking ahead.
*/
public class StandaloneUpgraderOnSStablesTest
{
String legacyId = LegacySSTableTest.legacyVersions[LegacySSTableTest.legacyVersions.length - 1];
@BeforeClass
public static void defineSchema() throws ConfigurationException
{
LegacySSTableTest.defineSchema();
System.setProperty(Util.ALLOW_TOOL_REINIT_FOR_TEST, "true"); // Necessary for testing
}
@AfterClass
public static void clearClassEnv()
{
System.clearProperty(Util.ALLOW_TOOL_REINIT_FOR_TEST);
}
@Test
public void testUpgradeKeepFiles() throws Throwable
{
LegacySSTableTest.truncateLegacyTables(legacyId);
LegacySSTableTest.loadLegacyTables(legacyId);
List<String> origFiles = getSStableFiles("legacy_tables", "legacy_" + legacyId + "_simple");
ToolResult tool = ToolRunner.invokeClass(StandaloneUpgrader.class,
"-k",
"legacy_tables",
"legacy_" + legacyId + "_simple");
Assertions.assertThat(tool.getStdout()).contains("Found 1 sstables that need upgrading.");
Assertions.assertThat(tool.getStdout()).contains("legacy_tables/legacy_" + legacyId + "_simple");
Assertions.assertThat(tool.getStdout()).contains("-Data.db");
tool.assertOnCleanExit();
List<String> newFiles = getSStableFiles("legacy_tables", "legacy_" + legacyId + "_simple");
origFiles.removeAll(newFiles);
assertEquals(0, origFiles.size()); // check previous version files are kept
// need to make sure the new sstables are live, so that they get truncated later
Keyspace.open("legacy_tables").getColumnFamilyStore("legacy_" + legacyId + "_simple").loadNewSSTables();
}
@Test
public void testUpgradeSnapshot() throws Throwable
{
LegacySSTableTest.truncateLegacyTables(legacyId);
LegacySSTableTest.loadLegacyTables(legacyId);
StorageService.instance.takeSnapshot("testsnapshot",
Collections.emptyMap(),
"legacy_tables.legacy_" + legacyId + "_simple");
ToolResult tool = ToolRunner.invokeClass(StandaloneUpgrader.class,
"-k",
"legacy_tables",
"legacy_" + legacyId + "_simple",
"wrongsnapshot");
Assertions.assertThat(tool.getStdout()).contains("Found 0 sstables that need upgrading.");
tool = ToolRunner.invokeClass(StandaloneUpgrader.class,
"legacy_tables",
"legacy_" + legacyId + "_simple",
"testsnapshot");
Assertions.assertThat(tool.getStdout()).contains("Found 1 sstables that need upgrading.");
Assertions.assertThat(tool.getStdout()).contains("legacy_tables/legacy_" + legacyId + "_simple");
Assertions.assertThat(tool.getStdout()).contains("-Data.db");
tool.assertOnCleanExit();
}
@Test
public void testUpgrade() throws Throwable
{
LegacySSTableTest.truncateLegacyTables(legacyId);
LegacySSTableTest.loadLegacyTables(legacyId);
List<String> origFiles = getSStableFiles("legacy_tables", "legacy_" + legacyId + "_simple");
ToolResult tool = ToolRunner.invokeClass(StandaloneUpgrader.class,
"legacy_tables",
"legacy_" + legacyId + "_simple");
Assertions.assertThat(tool.getStdout()).contains("Found 1 sstables that need upgrading.");
Assertions.assertThat(tool.getStdout()).contains("legacy_tables/legacy_" + legacyId + "_simple");
Assertions.assertThat(tool.getStdout()).contains("-Data.db");
tool.assertOnCleanExit();
List<String> newFiles = getSStableFiles("legacy_tables", "legacy_" + legacyId + "_simple");
int origSize = origFiles.size();
origFiles.removeAll(newFiles);
assertEquals(origSize, origFiles.size()); // check previous version files are gone
// need to make sure the new sstables are live, so that they get truncated later
Keyspace.open("legacy_tables").getColumnFamilyStore("legacy_" + legacyId + "_simple").loadNewSSTables();
}
private List<String> getSStableFiles(String ks, String table) throws StartupException
{
ColumnFamilyStore cfs = Keyspace.open(ks).getColumnFamilyStore(table);
org.apache.cassandra.Util.flush(cfs);
ColumnFamilyStore.scrubDataDirectories(cfs.metadata());
Set<SSTableReader> sstables = cfs.getLiveSSTables();
if (sstables.isEmpty())
return Lists.emptyList();
String sstableFileName = sstables.iterator().next().getFilename();
File sstablesDir = new File(sstableFileName).parent();
return Arrays.asList(sstablesDir.tryList())
.stream()
.filter(f -> f.isFile())
.map(file -> file.toString())
.collect(Collectors.toList());
}
}