diff options
Diffstat (limited to '')
-rw-r--r-- | src/test/librbd/crypto/test_mock_ShutDownCryptoRequest.cc | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/test/librbd/crypto/test_mock_ShutDownCryptoRequest.cc b/src/test/librbd/crypto/test_mock_ShutDownCryptoRequest.cc new file mode 100644 index 000000000..7df99b78a --- /dev/null +++ b/src/test/librbd/crypto/test_mock_ShutDownCryptoRequest.cc @@ -0,0 +1,174 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/crypto/Utils.h" +#include "test/librbd/test_mock_fixture.h" +#include "test/librbd/test_support.h" +#include "test/librbd/mock/MockImageCtx.h" +#include "test/librbd/mock/crypto/MockEncryptionFormat.h" + +#include "librbd/crypto/ShutDownCryptoRequest.cc" + +namespace librbd { + +namespace { + +struct MockTestImageCtx : public MockImageCtx { + MockTestImageCtx(librbd::ImageCtx &image_ctx) + : librbd::MockImageCtx(image_ctx) { + } + + MockTestImageCtx *parent = nullptr; +}; + +} // anonymous namespace + +namespace crypto { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; +using ::testing::WithArgs; + +struct TestMockShutDownCryptoRequest : public TestMockFixture { + typedef ShutDownCryptoRequest<MockTestImageCtx> MockShutDownCryptoRequest; + + MockTestImageCtx* mock_image_ctx; + C_SaferCond finished_cond; + Context *on_finish = &finished_cond; + MockShutDownCryptoRequest* mock_shutdown_crypto_request; + MockEncryptionFormat* mock_encryption_format; + Context* shutdown_object_dispatch_context; + Context* shutdown_image_dispatch_context; + + void SetUp() override { + TestMockFixture::SetUp(); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + mock_image_ctx = new MockTestImageCtx(*ictx); + mock_encryption_format = new MockEncryptionFormat(); + mock_image_ctx->encryption_format.reset(mock_encryption_format); + mock_shutdown_crypto_request = MockShutDownCryptoRequest::create( + mock_image_ctx, on_finish); + } + + void TearDown() override { + delete mock_image_ctx; + TestMockFixture::TearDown(); + } + + void expect_crypto_object_layer_exists_check( + MockTestImageCtx* image_ctx, bool exists) { + EXPECT_CALL(*image_ctx->io_object_dispatcher, exists( + io::OBJECT_DISPATCH_LAYER_CRYPTO)).WillOnce(Return(exists)); + } + + void expect_crypto_image_layer_exists_check( + MockTestImageCtx* image_ctx, bool exists) { + EXPECT_CALL(*image_ctx->io_image_dispatcher, exists( + io::IMAGE_DISPATCH_LAYER_CRYPTO)).WillOnce(Return(exists)); + } + + void expect_shutdown_crypto_object_dispatch(MockTestImageCtx* image_ctx) { + EXPECT_CALL(*image_ctx->io_object_dispatcher, shut_down_dispatch( + io::OBJECT_DISPATCH_LAYER_CRYPTO, _)).WillOnce( + WithArgs<1>(Invoke([this](Context* ctx) { + shutdown_object_dispatch_context = ctx; + }))); + } + + void expect_shutdown_crypto_image_dispatch(MockTestImageCtx* image_ctx) { + EXPECT_CALL(*image_ctx->io_image_dispatcher, shut_down_dispatch( + io::IMAGE_DISPATCH_LAYER_CRYPTO, _)).WillOnce( + WithArgs<1>(Invoke([this](Context* ctx) { + shutdown_image_dispatch_context = ctx; + }))); + } +}; + +TEST_F(TestMockShutDownCryptoRequest, NoCryptoObjectDispatch) { + expect_crypto_object_layer_exists_check(mock_image_ctx, false); + mock_shutdown_crypto_request->send(); + ASSERT_EQ(0, finished_cond.wait()); + ASSERT_EQ(nullptr, mock_image_ctx->encryption_format.get()); +} + +TEST_F(TestMockShutDownCryptoRequest, FailShutdownObjectDispatch) { + expect_crypto_object_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_object_dispatch(mock_image_ctx); + mock_shutdown_crypto_request->send(); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + shutdown_object_dispatch_context->complete(-EIO); + ASSERT_EQ(-EIO, finished_cond.wait()); + ASSERT_EQ(mock_encryption_format, mock_image_ctx->encryption_format.get()); +} + +TEST_F(TestMockShutDownCryptoRequest, NoCryptoImageDispatch) { + expect_crypto_object_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_object_dispatch(mock_image_ctx); + mock_shutdown_crypto_request->send(); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + expect_crypto_image_layer_exists_check(mock_image_ctx, false); + shutdown_object_dispatch_context->complete(0); + ASSERT_EQ(0, finished_cond.wait()); + ASSERT_EQ(nullptr, mock_image_ctx->encryption_format.get()); +} + +TEST_F(TestMockShutDownCryptoRequest, FailShutdownImageDispatch) { + expect_crypto_object_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_object_dispatch(mock_image_ctx); + mock_shutdown_crypto_request->send(); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + expect_crypto_image_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_image_dispatch(mock_image_ctx); + shutdown_object_dispatch_context->complete(0); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + shutdown_image_dispatch_context->complete(-EIO); + ASSERT_EQ(-EIO, finished_cond.wait()); + ASSERT_EQ(mock_encryption_format, mock_image_ctx->encryption_format.get()); +} + +TEST_F(TestMockShutDownCryptoRequest, Success) { + expect_crypto_object_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_object_dispatch(mock_image_ctx); + mock_shutdown_crypto_request->send(); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + expect_crypto_image_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_image_dispatch(mock_image_ctx); + shutdown_object_dispatch_context->complete(0); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + shutdown_image_dispatch_context->complete(0); + ASSERT_EQ(0, finished_cond.wait()); + ASSERT_EQ(nullptr, mock_image_ctx->encryption_format.get()); +} + +TEST_F(TestMockShutDownCryptoRequest, ShutdownParent) { + auto parent_image_ctx = new MockTestImageCtx(*mock_image_ctx->image_ctx); + mock_image_ctx->parent = parent_image_ctx; + expect_crypto_object_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_object_dispatch(mock_image_ctx); + mock_shutdown_crypto_request->send(); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + expect_crypto_image_layer_exists_check(mock_image_ctx, true); + expect_shutdown_crypto_image_dispatch(mock_image_ctx); + shutdown_object_dispatch_context->complete(0); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + expect_crypto_object_layer_exists_check(parent_image_ctx, true); + expect_shutdown_crypto_object_dispatch(parent_image_ctx); + shutdown_image_dispatch_context->complete(0); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + expect_crypto_image_layer_exists_check(parent_image_ctx, true); + expect_shutdown_crypto_image_dispatch(parent_image_ctx); + shutdown_object_dispatch_context->complete(0); + ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); + mock_image_ctx->parent = nullptr; + shutdown_image_dispatch_context->complete(0); + ASSERT_EQ(0, finished_cond.wait()); + ASSERT_EQ(nullptr, mock_image_ctx->encryption_format.get()); + ASSERT_EQ(nullptr, parent_image_ctx->encryption_format.get()); + delete parent_image_ctx; +} + +} // namespace crypto +} // namespace librbd |