Skip to content

Commit

Permalink
sstablemetadata unit test, docs and params parsing hardening
Browse files Browse the repository at this point in the history
Patch by Bereguer Blasi, reviewed by brandonwilliams for CASSANDRA-16016
  • Loading branch information
bereng authored and driftx committed Oct 6, 2020
1 parent 63b172e commit e8d3743
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 31 deletions.
8 changes: 6 additions & 2 deletions doc/source/tools/sstable/sstablemetadata.rst
Expand Up @@ -29,7 +29,11 @@ Usage
sstablemetadata <options> <sstable filename(s)>

========================= ================================================================================
--gc_grace_seconds <arg> The gc_grace_seconds to use when calculating droppable tombstones
-c,--colors Use ANSI color sequences
-g,--gc_grace_seconds <arg> Time to use when calculating droppable tombstones
-s,--scan Full sstable scan for additional details. Only available in 3.0+ sstables. Defaults: false
-t,--timestamp_unit <arg> Time unit that cell timestamps are written with
-u,--unicode Use unicode to draw histograms and progress bars
========================= ================================================================================

Print all the metadata
Expand Down Expand Up @@ -252,7 +256,7 @@ Example::
sstablemetadata --gc_grace_seconds 4700 /var/lib/cassandra/data/keyspace1/standard1-41b52700b4ed11e896476d2c86545d91/mc-12-big-Data.db | grep "Estimated droppable tombstones"
Estimated droppable tombstones: 9.61111111111111E-6

# if gc_grace_seconds was configured at 100, none of the tombstones would be currently droppable
# if gc_grace_seconds was configured at 5000, none of the tombstones would be currently droppable
sstablemetadata --gc_grace_seconds 5000 /var/lib/cassandra/data/keyspace1/standard1-41b52700b4ed11e896476d2c86545d91/mc-12-big-Data.db | grep "Estimated droppable tombstones"
Estimated droppable tombstones: 0.0

Expand Down
Expand Up @@ -73,7 +73,7 @@ public void testDefaultCall()
ToolResult tool = ToolRunner.invokeClass(SSTableLevelResetter.class, "--really-reset", "system_schema", "tables");
assertThat(tool.getStdout(), CoreMatchers.containsStringIgnoringCase("Found no sstables,"));
Assertions.assertThat(tool.getCleanedStderr()).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertCorrectEnvPostTest();
}

Expand Down
94 changes: 71 additions & 23 deletions test/unit/org/apache/cassandra/tools/SSTableMetadataViewerTest.java
Expand Up @@ -18,11 +18,14 @@

package org.apache.cassandra.tools;

import java.io.IOException;
import java.util.Arrays;

import org.apache.commons.codec.digest.DigestUtils;
import com.google.common.base.CharMatcher;

import org.apache.commons.lang3.tuple.Pair;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand All @@ -34,11 +37,18 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

@RunWith(OrderedJUnit4ClassRunner.class)
public class SSTableMetadataViewerTest extends OfflineToolUtils
{
private static String sstable;

@BeforeClass
public static void setupTest() throws IOException
{
sstable = findOneSSTable("legacy_sstables", "legacy_ma_simple");
}

@Test
public void testNoArgsPrintsHelp()
{
Expand Down Expand Up @@ -77,36 +87,63 @@ public void testMaybeChangeDocs()
@Test
public void testWrongArgFailsAndPrintsHelp()
{
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, "--debugwrong", "ks", "tab");
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, "--debugwrong", "sstableFile");
assertTrue(tool.getStdout(), tool.getStdout().isEmpty());
assertThat(tool.getCleanedStderr(), CoreMatchers.containsStringIgnoringCase("Options:"));
assertEquals(1, tool.getExitCode());
}

@Test
public void testDefaultCall()
public void testNAFileCall()
{
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, "ks", "tab");
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, "mockFile");
assertThat(tool.getStdout(), CoreMatchers.containsStringIgnoringCase("No such file"));
Assertions.assertThat(tool.getCleanedStderr()).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertGoodEnvPostTest();
}

@Test
public void testOnlySstableArg()
{
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, sstable);
Assertions.assertThat(tool.getStdout()).doesNotContain(Util.BLUE);
assertTrue(tool.getStdout(), CharMatcher.ascii().matchesAllOf(tool.getStdout()));
Assertions.assertThat(tool.getStdout()).doesNotContain("Widest Partitions");
Assertions.assertThat(tool.getStdout()).contains(sstable.replaceAll("-Data\\.db$", ""));
assertTrue(tool.getStderr(), tool.getStderr().isEmpty());
assertEquals(0, tool.getExitCode());
assertGoodEnvPostTest();
}

@Test
public void testFlagArgs()
public void testColorArg()
{
Arrays.asList("-c",
"--colors",
"-s",
"--scan",
"-u",
"--colors")
.stream()
.forEach(arg -> {
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, arg, sstable);
Assertions.assertThat(tool.getStdout()).contains(Util.BLUE);
Assertions.assertThat(tool.getStdout()).contains(sstable.replaceAll("-Data\\.db$", ""));
assertTrue("Arg: [" + arg + "]\n" + tool.getStderr(), tool.getStderr().isEmpty());
assertEquals(0, tool.getExitCode());
assertGoodEnvPostTest();
});
}

@Test
public void testUnicodeArg()
{
Arrays.asList("-u",
"--unicode")
.stream()
.forEach(arg -> {
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, arg, "ks", "tab");
assertThat("Arg: [" + arg + "]", tool.getStdout(), CoreMatchers.containsStringIgnoringCase("No such file"));
Assertions.assertThat(tool.getCleanedStderr()).as("Arg: [%s]", arg).isEmpty();
assertEquals(0,tool.getExitCode());
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, arg, sstable);
assertTrue(tool.getStdout(), !CharMatcher.ascii().matchesAllOf(tool.getStdout()));
Assertions.assertThat(tool.getStdout()).contains(sstable.replaceAll("-Data\\.db$", ""));
assertTrue("Arg: [" + arg + "]\n" + tool.getStderr(), tool.getStderr().isEmpty());
assertEquals(0, tool.getExitCode());
assertGoodEnvPostTest();
});
}
Expand All @@ -122,8 +159,7 @@ public void testGCArg()
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class,
arg.getLeft(),
arg.getRight(),
"ks",
"tab");
"mockFile");
assertEquals(-1, tool.getExitCode());
Assertions.assertThat(tool.getStderr()).contains(NumberFormatException.class.getSimpleName());
});
Expand All @@ -132,8 +168,7 @@ public void testGCArg()
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class,
arg.getLeft(),
arg.getRight(),
"ks",
"tab");
"mockFile");
assertThat("Arg: [" + arg + "]", tool.getStdout(), CoreMatchers.containsStringIgnoringCase("No such file"));
Assertions.assertThat(tool.getCleanedStderr()).as("Arg: [%s]", arg).isEmpty();
tool.assertOnExitCode();
Expand All @@ -152,8 +187,7 @@ public void testTSUnitArg()
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class,
arg.getLeft(),
arg.getRight(),
"ks",
"tab");
"mockFile");
assertEquals(-1, tool.getExitCode());
Assertions.assertThat(tool.getStderr()).contains(IllegalArgumentException.class.getSimpleName());
});
Expand All @@ -162,15 +196,29 @@ public void testTSUnitArg()
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class,
arg.getLeft(),
arg.getRight(),
"ks",
"tab");
"mockFile");
assertThat("Arg: [" + arg + "]", tool.getStdout(), CoreMatchers.containsStringIgnoringCase("No such file"));
Assertions.assertThat(tool.getCleanedStderr()).as("Arg: [%s]", arg).isEmpty();
tool.assertOnExitCode();
assertGoodEnvPostTest();
});
}

@Test
public void testScanArg()
{
Arrays.asList("-s",
"--scan")
.stream()
.forEach(arg -> {
ToolResult tool = ToolRunner.invokeClass(SSTableMetadataViewer.class, arg, sstable);
Assertions.assertThat(tool.getStdout()).contains("Widest Partitions");
Assertions.assertThat(tool.getStdout()).contains(sstable.replaceAll("-Data\\.db$", ""));
assertTrue("Arg: [" + arg + "]\n" + tool.getStderr(), tool.getStderr().isEmpty());
assertEquals(0, tool.getExitCode());
});
}

private void assertGoodEnvPostTest()
{
assertNoUnexpectedThreadsStarted(null, OPTIONAL_THREADS_WITH_SCHEMA);
Expand Down
Expand Up @@ -86,7 +86,7 @@ public void testDefaultCall()
ToolResult tool = ToolRunner.invokeClass(StandaloneSSTableUtil.class, "system_schema", "tables");
assertThat(tool.getStdout(), CoreMatchers.containsStringIgnoringCase("Listing files..."));
Assertions.assertThat(tool.getCleanedStderr()).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertCorrectEnvPostTest();
}

Expand Down
Expand Up @@ -101,7 +101,7 @@ public void testDefaultCall()
ToolResult tool = ToolRunner.invokeClass(StandaloneScrubber.class, "system_schema", "tables");
assertThat(tool.getStdout(), CoreMatchers.containsStringIgnoringCase("Pre-scrub sstables snapshotted into snapshot"));
Assertions.assertThat(tool.getCleanedStderr()).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertCorrectEnvPostTest();
}

Expand Down
Expand Up @@ -87,7 +87,7 @@ public void testDefaultCall()
ToolResult tool = ToolRunner.invokeClass(StandaloneUpgrader.class, "system_schema", "tables");
Assertions.assertThat(tool.getStdout()).isEqualTo("Found 0 sstables that need upgrading.\n");
Assertions.assertThat(tool.getCleanedStderr()).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertCorrectEnvPostTest();
}

Expand All @@ -101,7 +101,7 @@ public void testFlagArgs()
"tables");
Assertions.assertThat(tool.getStdout()).as("Arg: [%s]", arg).isEqualTo("Found 0 sstables that need upgrading.\n");
Assertions.assertThat(tool.getCleanedStderr()).as("Arg: [%s]", arg).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertCorrectEnvPostTest();
});
}
Expand Down
Expand Up @@ -87,7 +87,7 @@ public void testDefaultCall()
ToolResult tool = ToolRunner.invokeClass(StandaloneVerifier.class, "system_schema", "tables");
assertThat(tool.getStdout(), CoreMatchers.containsStringIgnoringCase("using the following options"));
Assertions.assertThat(tool.getCleanedStderr()).isEmpty();
assertEquals(0,tool.getExitCode());
assertEquals(0, tool.getExitCode());
assertCorrectEnvPostTest();
}

Expand Down

0 comments on commit e8d3743

Please sign in to comment.