summaryrefslogtreecommitdiffstats
path: root/memfilepersistence/src/tests/tools
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /memfilepersistence/src/tests/tools
Publish
Diffstat (limited to 'memfilepersistence/src/tests/tools')
-rw-r--r--memfilepersistence/src/tests/tools/.gitignore2
-rw-r--r--memfilepersistence/src/tests/tools/CMakeLists.txt7
-rw-r--r--memfilepersistence/src/tests/tools/dumpslotfiletest.cpp138
-rw-r--r--memfilepersistence/src/tests/tools/vdsdisktooltest.cpp108
4 files changed, 255 insertions, 0 deletions
diff --git a/memfilepersistence/src/tests/tools/.gitignore b/memfilepersistence/src/tests/tools/.gitignore
new file mode 100644
index 00000000000..7e7c0fe7fae
--- /dev/null
+++ b/memfilepersistence/src/tests/tools/.gitignore
@@ -0,0 +1,2 @@
+/.depend
+/Makefile
diff --git a/memfilepersistence/src/tests/tools/CMakeLists.txt b/memfilepersistence/src/tests/tools/CMakeLists.txt
new file mode 100644
index 00000000000..aef718c7633
--- /dev/null
+++ b/memfilepersistence/src/tests/tools/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_library(memfilepersistence_testtools
+ SOURCES
+ dumpslotfiletest.cpp
+ vdsdisktooltest.cpp
+ DEPENDS
+)
diff --git a/memfilepersistence/src/tests/tools/dumpslotfiletest.cpp b/memfilepersistence/src/tests/tools/dumpslotfiletest.cpp
new file mode 100644
index 00000000000..112f8840e72
--- /dev/null
+++ b/memfilepersistence/src/tests/tools/dumpslotfiletest.cpp
@@ -0,0 +1,138 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/fastos/fastos.h>
+#include <vespa/config/subscription/configuri.h>
+#include <vespa/document/base/testdocrepo.h>
+#include <vespa/memfilepersistence/tools/dumpslotfile.h>
+#include <vespa/vdstestlib/cppunit/macros.h>
+#include <vespa/vespalib/util/programoptions_testutils.h>
+#include <tests/spi/memfiletestutils.h>
+
+#include <vespa/document/config/config-documenttypes.h>
+
+namespace storage {
+namespace memfile {
+
+class DumpSlotFileTest : public SingleDiskMemFileTestUtils
+{
+ CPPUNIT_TEST_SUITE(DumpSlotFileTest);
+ CPPUNIT_TEST(testSimple);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testSimple();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DumpSlotFileTest);
+
+#define ASSERT_MATCH(optstring, pattern) \
+{ \
+ vespalib::AppOptions opts("dumpslotfile " optstring); \
+ std::ostringstream out; \
+ config::ConfigUri configUri(config::ConfigUri::createFromInstance( \
+ document::TestDocRepo::getDefaultConfig())); \
+ std::unique_ptr<document::DocumenttypesConfig> config = config::ConfigGetter<document::DocumenttypesConfig>::getConfig(configUri.getConfigId(), configUri.getContext()); \
+ SlotFileDumper::dump(opts.getArgCount(), opts.getArguments(), \
+ configUri, out, out); \
+ CPPUNIT_ASSERT_MATCH_REGEX(pattern, out.str()); \
+ output = out.str(); \
+}
+
+void
+DumpSlotFileTest::testSimple()
+{
+ std::string output;
+ // Test syntax page
+ ASSERT_MATCH("--help", ".*Usage: dumpslotfile.*");
+ // Test non-existing file. (Handle as empty file)
+ ASSERT_MATCH("00a.0",
+ ".*BucketId\\(0x000000000000000a\\)"
+ ".*document count: 0.*non-existing.*");
+ // Parse bucketid without extension.
+ ASSERT_MATCH("000000000000000a",
+ ".*BucketId\\(0x000000000000000a\\) "
+ "\\(extracted from filename\\).*");
+ // Parse invalid bucket id.
+ ASSERT_MATCH("000010000000000g",
+ ".*Failed to extract bucket id from filename.*");
+ // Test toXml with no data. Thus doesn't require doc config
+ ASSERT_MATCH("--toxml --documentconfig whatevah 000a.0",
+ ".*<vespafeed>.*");
+ // Test invalid arguments
+ ASSERT_MATCH("--foobar", ".*Invalid option 'foobar'\\..*");
+ // What to show in XML doesn't make sense in non-xml mode
+ ASSERT_MATCH("--includeremoveddocs 0.0",
+ ".*Options for what to include in XML makes no sense when not "
+ "printing XML content.*");
+ ASSERT_MATCH("--includeremoveentries 0.0",
+ ".*Options for what to include in XML makes no sense when not "
+ "printing XML content.*");
+ // To binary only works for single doc
+ ASSERT_MATCH("--tobinary 0.0",
+ ".*To binary option only works for a single document.*");
+
+ BucketId bid(1, 0);
+ createTestBucket(bid, 0);
+ ASSERT_MATCH("-nN vdsroot/disks/d0/400000000000000.0",
+ ".*"
+ "Unique document count: 8.*"
+ "Total document size: [0-9]+.*"
+ "Used size: [0-9]+.*"
+ "Filename: .*/d0/.*"
+ "Filesize: 12288.*"
+ "SlotFileHeader.*"
+ "[0-9]+ empty entries.*"
+ "Header block.*"
+ "Content block.*"
+ "Slotfile verified.*"
+ );
+ ASSERT_MATCH("vdsroot/disks/d0/400000000000000.0", ".*ff ff ff ff.*");
+
+ // User friendly output
+ ASSERT_MATCH("--friendly -nN vdsroot/disks/d0/400000000000000.0",
+ ".*id:mail:testdoctype1:n=0:9380.html.*");
+
+ ASSERT_MATCH("--tobinary "
+ "--docid id:mail:testdoctype1:n=0:doesnotexisthere.html "
+ "vdsroot/disks/d0/400000000000000.0",
+ ".*No document with id id:mail:testdoctype1:n=0:doesnotexi.* "
+ "found.*");
+
+ // Should test XML with content.. But needs document config for it to work.
+ // Should be able to create programmatically from testdocman.
+ ASSERT_MATCH("--toxml --documentconfig '' "
+ "vdsroot/disks/d0/400000000000000.0",
+ ".*<vespafeed>\n"
+ "<document documenttype=\"testdoctype1\" "
+ "documentid=\"id:mail:testdoctype1:n=0:9639.html\">\n"
+ "<content>overwritten</content>\n"
+ "</document>.*");
+
+ // To binary
+ ASSERT_MATCH("--tobinary --docid id:mail:testdoctype1:n=0:9380.html "
+ "vdsroot/disks/d0/400000000000000.0",
+ ".*");
+ {
+ TestDocMan docMan;
+ document::ByteBuffer buf(output.c_str(), output.size());
+ document::Document doc(docMan.getTypeRepo(), buf);
+ CPPUNIT_ASSERT_EQUAL(std::string(
+ "<document documenttype=\"testdoctype1\" "
+ "documentid=\"id:mail:testdoctype1:n=0:9380.html\">\n"
+ "<content>To be, or not to be: that is the question:\n"
+ "Whether 'tis nobler in the mind to suffer\n"
+ "The slings and arrows of outrage</content>\n"
+ "</document>"), doc.toXml());
+ }
+
+ // Fail verification
+ {
+ vespalib::LazyFile file("vdsroot/disks/d0/400000000000000.0", 0);
+ file.write("corrupt", 7, 64);
+ }
+ ASSERT_MATCH("-nN vdsroot/disks/d0/400000000000000.0",
+ ".*lot 0 at timestamp [0-9]+ failed checksum verification.*");
+}
+
+} // memfile
+} // storage
diff --git a/memfilepersistence/src/tests/tools/vdsdisktooltest.cpp b/memfilepersistence/src/tests/tools/vdsdisktooltest.cpp
new file mode 100644
index 00000000000..29e780bc900
--- /dev/null
+++ b/memfilepersistence/src/tests/tools/vdsdisktooltest.cpp
@@ -0,0 +1,108 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/fastos/fastos.h>
+#include <vespa/config/subscription/configuri.h>
+#include <vespa/memfilepersistence/tools/vdsdisktool.h>
+#include <vespa/storageframework/defaultimplementation/clock/fakeclock.h>
+#include <vespa/vdstestlib/cppunit/macros.h>
+#include <vespa/vespalib/util/programoptions_testutils.h>
+#include <tests/spi/memfiletestutils.h>
+
+namespace storage {
+namespace memfile {
+
+struct VdsDiskToolTest : public SingleDiskMemFileTestUtils
+{
+ framework::defaultimplementation::FakeClock _clock;
+ DeviceManager::LP _deviceManager;
+
+ void setUp();
+ void setupRoot();
+
+ void testSimple();
+
+ CPPUNIT_TEST_SUITE(VdsDiskToolTest);
+ CPPUNIT_TEST(testSimple);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(VdsDiskToolTest);
+
+#define ASSERT_MATCH(optstring, pattern, exitcode) \
+{ \
+ std::ostringstream out; \
+ int result = 1; \
+ try{ \
+ vespalib::AppOptions opts("vdsdisktool " optstring); \
+ result = VdsDiskTool::run(opts.getArgCount(), opts.getArguments(), \
+ "vdsroot", out, out); \
+ } catch (std::exception& e) { \
+ out << "Application aborted with exception:\n" << e.what() << "\n"; \
+ } \
+ CPPUNIT_ASSERT_MATCH_REGEX(pattern, out.str()); \
+ CPPUNIT_ASSERT_EQUAL(exitcode, result); \
+}
+
+namespace {
+ void createDisk(int i) {
+ std::ostringstream path;
+ path << "vdsroot/mycluster/storage/3/disks/d" << i;
+ CPPUNIT_ASSERT_EQUAL(0, system(("mkdir -p " + path.str()).c_str()));
+ }
+}
+
+void
+VdsDiskToolTest::setUp()
+{
+ system("rm -rf vdsroot");
+ _deviceManager.reset(new DeviceManager(
+ DeviceMapper::UP(new SimpleDeviceMapper), _clock));
+}
+
+void
+VdsDiskToolTest::setupRoot()
+{
+ system("rm -rf vdsroot");
+ createDisk(0);
+}
+
+void
+VdsDiskToolTest::testSimple()
+{
+ // Test syntax page
+ ASSERT_MATCH("--help", ".*Usage: vdsdisktool .*", 0);
+ // No VDS installation
+ ASSERT_MATCH("status", ".*No VDS installations found at all.*", 1);
+ // Common setup
+ setupRoot();
+ ASSERT_MATCH("status", ".*Disks on storage node 3 in cluster mycluster:\\s*"
+ "Disk 0: OK\\s*", 0);
+ // Two disks
+ system("mkdir -p vdsroot/mycluster/storage/3/disks/d1/");
+ ASSERT_MATCH("status", ".*Disks on storage node 3 in cluster mycluster:\\s*"
+ "Disk 0: OK\\s*"
+ "Disk 1: OK\\s*", 0);
+ // Two disks, non-continuous indexes
+ system("rm -rf vdsroot/mycluster/storage/3/disks/d1/");
+ system("mkdir -p vdsroot/mycluster/storage/3/disks/d2/");
+ ASSERT_MATCH("status", ".*Disks on storage node 3 in cluster mycluster:\\s*"
+ "Disk 0: OK\\s*"
+ "Disk 1: NOT_FOUND - Disk not found during scan.*"
+ "Disk 2: OK\\s*", 0);
+ // Status file existing
+ setupRoot();
+ createDisk(1);
+ MountPointList mountPoints("vdsroot/mycluster/storage/3",
+ std::vector<vespalib::string>(),
+ _deviceManager);
+ mountPoints.scanForDisks();
+ CPPUNIT_ASSERT_EQUAL(2u, mountPoints.getSize());
+ mountPoints[1].addEvent(Device::IO_FAILURE, "Bad", "Found in test");
+ mountPoints.writeToFile();
+ ASSERT_MATCH("status", ".*Disks on storage node 3 in cluster mycluster:\\s*"
+ "Disk 0: OK\\s*"
+ "Disk 1: IO_FAILURE - 0 Bad\\s*", 0);
+}
+
+} // memfile
+} // storage