diff options
author | Tor Brede Vekterli <vekterli@yahoo-inc.com> | 2017-08-31 12:06:53 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@yahoo-inc.com> | 2017-08-31 15:22:15 +0000 |
commit | bd2827d46947646a538e256a4e656c8f94438917 (patch) | |
tree | dbaad465b045df560188cb94718b54d280dfe9ad /storage/src/tests/persistence/provider_error_wrapper_test.cpp | |
parent | 239ccaca10f97e9e4038ae48604e248e14074eb3 (diff) |
Wire together new listener to propagate errors
Diffstat (limited to 'storage/src/tests/persistence/provider_error_wrapper_test.cpp')
-rw-r--r-- | storage/src/tests/persistence/provider_error_wrapper_test.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/storage/src/tests/persistence/provider_error_wrapper_test.cpp b/storage/src/tests/persistence/provider_error_wrapper_test.cpp new file mode 100644 index 00000000000..94a2586f0d8 --- /dev/null +++ b/storage/src/tests/persistence/provider_error_wrapper_test.cpp @@ -0,0 +1,141 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/vdstestlib/cppunit/macros.h> +#include <tests/persistence/persistencetestutils.h> +#include <tests/persistence/common/persistenceproviderwrapper.h> + +namespace storage { + +class ProviderErrorWrapperTest : public SingleDiskPersistenceTestUtils { +public: + CPPUNIT_TEST_SUITE(ProviderErrorWrapperTest); + CPPUNIT_TEST(fatal_error_invokes_listener); + CPPUNIT_TEST(resource_exhaustion_error_invokes_listener); + CPPUNIT_TEST(listener_not_invoked_on_success); + CPPUNIT_TEST(listener_not_invoked_on_regular_errors); + CPPUNIT_TEST(multiple_listeners_can_be_registered); + CPPUNIT_TEST_SUITE_END(); + + void fatal_error_invokes_listener(); + void resource_exhaustion_error_invokes_listener(); + void listener_not_invoked_on_success(); + void listener_not_invoked_on_regular_errors(); + void multiple_listeners_can_be_registered(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(ProviderErrorWrapperTest); + +namespace { + +struct MockErrorListener : ProviderErrorListener { + void on_fatal_error(vespalib::stringref message) override { + _seen_fatal_error = true; + _fatal_error = message; + } + void on_resource_exhaustion_error(vespalib::stringref message) override { + _seen_resource_exhaustion_error = true; + _resource_exhaustion_error = message; + } + + vespalib::string _fatal_error; + vespalib::string _resource_exhaustion_error; + bool _seen_fatal_error{false}; + bool _seen_resource_exhaustion_error{false}; +}; + +struct Fixture { + // We wrap the wrapper. It's turtles all the way down! + PersistenceProviderWrapper providerWrapper; + TestServiceLayerApp app; + ServiceLayerComponent component; + ProviderErrorWrapper errorWrapper; + + Fixture(spi::PersistenceProvider& provider) + : providerWrapper(provider), + app(), + component(app.getComponentRegister(), "dummy"), + errorWrapper(providerWrapper) + { + providerWrapper.setFailureMask(PersistenceProviderWrapper::FAIL_ALL_OPERATIONS); + } + ~Fixture() {} + + void perform_spi_operation() { + errorWrapper.getBucketInfo(spi::Bucket(document::BucketId(16, 1234), spi::PartitionId(0))); + } +}; + +} + +void ProviderErrorWrapperTest::fatal_error_invokes_listener() { + Fixture f(getPersistenceProvider()); + auto listener = std::make_shared<MockErrorListener>(); + f.errorWrapper.register_error_listener(listener); + f.providerWrapper.setResult(spi::Result(spi::Result::FATAL_ERROR, "eject! eject!")); + + CPPUNIT_ASSERT(!listener->_seen_fatal_error); + f.perform_spi_operation(); + + CPPUNIT_ASSERT(!listener->_seen_resource_exhaustion_error); + CPPUNIT_ASSERT(listener->_seen_fatal_error); + CPPUNIT_ASSERT_EQUAL(vespalib::string("eject! eject!"), listener->_fatal_error); +} + +void ProviderErrorWrapperTest::resource_exhaustion_error_invokes_listener() { + Fixture f(getPersistenceProvider()); + auto listener = std::make_shared<MockErrorListener>(); + f.errorWrapper.register_error_listener(listener); + f.providerWrapper.setResult(spi::Result(spi::Result::RESOURCE_EXHAUSTED, "out of juice")); + + CPPUNIT_ASSERT(!listener->_seen_resource_exhaustion_error); + f.perform_spi_operation(); + + CPPUNIT_ASSERT(!listener->_seen_fatal_error); + CPPUNIT_ASSERT(listener->_seen_resource_exhaustion_error); + CPPUNIT_ASSERT_EQUAL(vespalib::string("out of juice"), listener->_resource_exhaustion_error); +} + +void ProviderErrorWrapperTest::listener_not_invoked_on_success() { + Fixture f(getPersistenceProvider()); + auto listener = std::make_shared<MockErrorListener>(); + f.errorWrapper.register_error_listener(listener); + f.perform_spi_operation(); + + CPPUNIT_ASSERT(!listener->_seen_fatal_error); + CPPUNIT_ASSERT(!listener->_seen_resource_exhaustion_error); +} + +void ProviderErrorWrapperTest::listener_not_invoked_on_regular_errors() { + Fixture f(getPersistenceProvider()); + auto listener = std::make_shared<MockErrorListener>(); + f.errorWrapper.register_error_listener(listener); + + // TODO dedupe + f.providerWrapper.setResult(spi::Result(spi::Result::TRANSIENT_ERROR, "beep boop")); + f.perform_spi_operation(); + CPPUNIT_ASSERT(!listener->_seen_fatal_error); + CPPUNIT_ASSERT(!listener->_seen_resource_exhaustion_error); + + f.providerWrapper.setResult(spi::Result(spi::Result::PERMANENT_ERROR, "beep boop!!")); + f.perform_spi_operation(); + CPPUNIT_ASSERT(!listener->_seen_fatal_error); + CPPUNIT_ASSERT(!listener->_seen_resource_exhaustion_error); +} + +void ProviderErrorWrapperTest::multiple_listeners_can_be_registered() { + Fixture f(getPersistenceProvider()); + auto listener1 = std::make_shared<MockErrorListener>(); + auto listener2 = std::make_shared<MockErrorListener>(); + f.errorWrapper.register_error_listener(listener1); + f.errorWrapper.register_error_listener(listener2); + + f.providerWrapper.setResult(spi::Result(spi::Result::RESOURCE_EXHAUSTED, "out of juice")); + f.perform_spi_operation(); + + CPPUNIT_ASSERT(listener1->_seen_resource_exhaustion_error); + CPPUNIT_ASSERT(listener2->_seen_resource_exhaustion_error); +} + +} // ns storage + + |