Skip to content

Commit

Permalink
#62: alt_copy unit test + bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jrse committed May 14, 2018
1 parent 0c52271 commit d66d2de
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/storage-rbox/rbox-copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ int rbox_mail_storage_copy(struct mail_save_context *ctx, struct mail *mail) {
enum mail_flags flags = index_mail_get_flags(mail);
bool alt_storage = is_alternate_storage_set(flags);

if (rbox_open_rados_connection(dest_mbox, alt_storage) < 0) {
if (rbox_open_rados_connection(mail->box, alt_storage) < 0) {
FUNC_END_RET("ret == -1, connection to rados failed");
return -1;
}
Expand Down
10 changes: 5 additions & 5 deletions src/storage-rbox/rbox-storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct mail_storage *rbox_storage_alloc(void) {
storage->config = new librmb::RadosDovecotCephCfgImpl(&storage->s->get_io_ctx());
storage->ns_mgr = new librmb::RadosNamespaceManager(storage->config);
storage->ms = new librmb::RadosMetadataStorageImpl();

storage->alt = new librmb::RadosStorageImpl(storage->cluster);
FUNC_END();
return &storage->storage;
}
Expand Down Expand Up @@ -366,16 +366,16 @@ int rbox_open_rados_connection(struct mailbox *box, bool alt_storage) {
mbox->storage->config->get_rados_username());

if (alt_storage) {
i_debug("using alt storage %s", box->list->set.alt_dir);
mbox->storage->alt = new librmb::RadosStorageImpl(mbox->storage->cluster);
ret = mbox->storage->alt->open_connection(box->list->set.alt_dir, mbox->storage->config->get_rados_cluster_name(),
mbox->storage->config->get_rados_username());
//}
}
/*TODO: if (ret == 1) {
/*TODO:*/
if (ret == 1) {
// already connected nothing to do!
FUNC_END();
return 0;
}*/
}
if (ret < 0) {
i_debug("Error = %d", ret);
return ret;
Expand Down
5 changes: 5 additions & 0 deletions src/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ it_test_copy_rbox_SOURCES = storage-rbox/it_test_copy_rbox.cpp storage-rbox/Test
it_test_copy_rbox_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDOVECOT_INCLUDE)
it_test_copy_rbox_LDADD = $(storage_shlibs) $(gtest_shlibs)

TESTS += it_test_copy_rbox_alt
it_test_copy_rbox_alt_SOURCES = storage-rbox/it_test_copy_rbox_alt.cpp storage-rbox/TestCase.cpp storage-rbox/TestCase.h test-utils/it_utils.cpp test-utils/it_utils.h
it_test_copy_rbox_alt_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDOVECOT_INCLUDE)
it_test_copy_rbox_alt_LDADD = $(storage_shlibs) $(gtest_shlibs)

TESTS += it_test_copy_rbox_fail
it_test_copy_rbox_fail_SOURCES = storage-rbox/it_test_copy_rbox_fail.cpp storage-rbox/TestCase.cpp storage-rbox/TestCase.h test-utils/it_utils.cpp test-utils/it_utils.h
it_test_copy_rbox_fail_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDOVECOT_INCLUDE)
Expand Down
206 changes: 206 additions & 0 deletions src/tests/storage-rbox/it_test_copy_rbox_alt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Copyright (c) 2017-2018 Tallence AG and the authors
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*/

#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "TestCase.h"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow" // turn off warnings for Dovecot :-(
#pragma GCC diagnostic ignored "-Wundef" // turn off warnings for Dovecot :-(
#pragma GCC diagnostic ignored "-Wredundant-decls" // turn off warnings for Dovecot :-(
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" // turn off warnings for Dovecot :-(
#endif

extern "C" {
#include "lib.h"
#include "mail-user.h"
#include "mail-storage.h"
#include "mail-storage-service.h"
#include "mail-namespace.h"
#include "mailbox-list.h"
#include "ioloop.h"
#include "istream.h"
#include "mail-search-build.h"

#include "libdict-rados-plugin.h"
#include "mail-search-parser-private.h"
#include "mail-search.h"
}
#include "rbox-storage.hpp"
#include "../mocks/mock_test.h"
#include "dovecot-ceph-plugin-config.h"
#include "../test-utils/it_utils.h"
#include "rbox-mail.h"
#include "rbox-storage.h"
#include "rados-util.h"
using ::testing::AtLeast;
using ::testing::Return;

TEST_F(StorageTest, init) {}

TEST_F(StorageTest, mailbox_open_inbox) {
struct mail_namespace *ns = mail_namespace_find_inbox(s_test_mail_user->namespaces);
struct mailbox *box = mailbox_alloc(ns->list, "INBOX", MAILBOX_FLAG_READONLY);
ASSERT_GE(mailbox_open(box), 0);
mailbox_free(&box);
}

TEST_F(StorageTest, mail_copy_mail_in_inbox) {
struct mailbox_transaction_context *desttrans;
struct mail_save_context *save_ctx;
struct mail *mail;
struct mail_search_context *search_ctx;
struct mail_search_args *search_args;
struct mail_search_arg *sarg;

const char *message =
"From: [email protected]\n"
"Date: Sat, 24 Mar 2017 23:00:00 +0200\n"
"Mime-Version: 1.0\n"
"Content-Type: text/plain; charset=us-ascii\n"
"\n"
"body\n";

const char *mailbox = "INBOX";

// testdata
testutils::ItUtils::add_mail(message, mailbox, StorageTest::s_test_mail_user->namespaces);

i_debug("mail_ added ");

search_args = mail_search_build_init();
sarg = mail_search_build_add(search_args, SEARCH_ALL);
ASSERT_NE(sarg, nullptr);

struct mail_namespace *ns = mail_namespace_find_inbox(s_test_mail_user->namespaces);
ASSERT_NE(ns, nullptr);

struct mailbox *box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_SAVEONLY);

if (mailbox_open(box) < 0) {
i_error("Opening mailbox %s failed: %s", mailbox, mailbox_get_last_internal_error(box, NULL));
FAIL() << " Forcing a resync on mailbox INBOX Failed";
}

#ifdef DOVECOT_CEPH_PLUGIN_HAVE_MAIL_STORAGE_TRANSACTION_OLD_SIGNATURE
desttrans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
#else
char reason[256];
memset(reason, '\0', sizeof(reason));
desttrans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL, reason);
#endif

search_ctx = mailbox_search_init(desttrans, search_args, NULL, static_cast<mail_fetch_field>(0), NULL);
mail_search_args_unref(&search_args);

while (mailbox_search_next(search_ctx, &mail)) {
save_ctx = mailbox_save_alloc(desttrans); // src save context

// 1. read index to get oid
// 2. move mail to alt
// 3. update index.
// see what happends
std::string alt_dir = "mail_storage_alt_test_copy";
box->list->set.alt_dir = alt_dir.c_str();

i_debug("SETTING UPDATE_FLAG ");
mail_update_flags(mail, MODIFY_ADD, (enum mail_flags)MAIL_INDEX_MAIL_FLAG_BACKEND);
rbox_get_index_record(mail);
struct rbox_mail *r_mail = (struct rbox_mail *)mail;
i_debug("end %s", r_mail->mail_object->get_oid().c_str());
if (rbox_open_rados_connection(box, true) < 0) {
FAIL() << "connection error alt";
} else {
struct rbox_mailbox *mbox = (struct rbox_mailbox *)box;
// MOVE TO ALT
std::string oid = r_mail->mail_object->get_oid();
librmb::RadosUtils::move_to_alt(oid, mbox->storage->s, mbox->storage->alt, mbox->storage->ms, false);
}

mailbox_save_copy_flags(save_ctx, mail);

int ret2 = mailbox_copy(&save_ctx, mail);
EXPECT_EQ(ret2, 0);
break; // only move one mail.
}

if (mailbox_search_deinit(&search_ctx) < 0) {
FAIL() << "search deinit failed";
}

if (mailbox_transaction_commit(&desttrans) < 0) {
FAIL() << "tnx commit failed";
}
if (mailbox_sync(box, static_cast<mailbox_sync_flags>(0)) < 0) {
FAIL() << "sync failed";
}
struct rbox_storage *r_storage = (struct rbox_storage *)box->storage;

librados::NObjectIterator iter_alt(r_storage->alt->get_io_ctx().nobjects_begin());
r_storage->ms->get_storage()->set_io_ctx(&r_storage->alt->get_io_ctx());
std::vector<librmb::RadosMailObject *> objects_alt;
while (iter_alt != librados::NObjectIterator::__EndObjectIterator) {
librmb::RadosMailObject *obj = new librmb::RadosMailObject();
obj->set_oid((*iter_alt).get_oid());
r_storage->ms->get_storage()->load_metadata(obj);
objects_alt.push_back(obj);
iter_alt++;
}
r_storage->ms->get_storage()->set_io_ctx(&r_storage->s->get_io_ctx());
ASSERT_EQ(2, (int)objects_alt.size());
librmb::RadosMailObject *mail1 = objects_alt[0];
librmb::RadosMailObject *mail2 = objects_alt[1];

ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_OLDV1_FLAGS),
mail2->get_metadata(librmb::RBOX_METADATA_OLDV1_FLAGS));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_EXT_REF), mail2->get_metadata(librmb::RBOX_METADATA_EXT_REF));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_FROM_ENVELOPE),
mail2->get_metadata(librmb::RBOX_METADATA_FROM_ENVELOPE));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_GUID), mail2->get_metadata(librmb::RBOX_METADATA_GUID));

ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_MAILBOX_GUID),
mail2->get_metadata(librmb::RBOX_METADATA_MAILBOX_GUID));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_ORIG_MAILBOX),
mail2->get_metadata(librmb::RBOX_METADATA_ORIG_MAILBOX));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_PHYSICAL_SIZE),
mail2->get_metadata(librmb::RBOX_METADATA_PHYSICAL_SIZE));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_POP3_ORDER),
mail2->get_metadata(librmb::RBOX_METADATA_POP3_ORDER));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_POP3_UIDL), mail2->get_metadata(librmb::RBOX_METADATA_POP3_UIDL));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_PVT_FLAGS), mail2->get_metadata(librmb::RBOX_METADATA_PVT_FLAGS));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_RECEIVED_TIME),
mail2->get_metadata(librmb::RBOX_METADATA_RECEIVED_TIME));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_VERSION), mail2->get_metadata(librmb::RBOX_METADATA_VERSION));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_VIRTUAL_SIZE),
mail2->get_metadata(librmb::RBOX_METADATA_VIRTUAL_SIZE));
ASSERT_EQ(mail1->get_metadata(librmb::RBOX_METADATA_OLDV1_SAVE_TIME),
mail2->get_metadata(librmb::RBOX_METADATA_OLDV1_SAVE_TIME));

ASSERT_NE(mail1->get_metadata(librmb::RBOX_METADATA_MAIL_UID), mail2->get_metadata(librmb::RBOX_METADATA_MAIL_UID));

ASSERT_EQ(2, (int)box->index->map->hdr.messages_count);
r_storage->alt->delete_mail(mail1);
r_storage->alt->delete_mail(mail2);

delete mail1;
delete mail2;

mailbox_free(&box);
}

TEST_F(StorageTest, deinit) {}

int main(int argc, char **argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
2 changes: 0 additions & 2 deletions src/tests/storage-rbox/it_test_read_mail_rbox_alt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,6 @@ TEST_F(StorageTest, mail_copy_mail_in_inbox) {
// MOVE TO ALT
std::string oid = r_mail->mail_object->get_oid();
librmb::RadosUtils::move_to_alt(oid, mbox->storage->s, mbox->storage->alt, mbox->storage->ms, false);
mbox->storage->alt->close_connection();
delete mbox->storage->alt;
}

int ret2 = mail_get_stream(mail, &hdr_size, &body_size, &input);
Expand Down

0 comments on commit d66d2de

Please sign in to comment.