Skip to content

Commit 3c0339f

Browse files
Tim Bradgatedaverigby
authored andcommitted
MB-29816: Properly handle return codes from couchstore within couch-kvstore
Whilst this is not the cause of the issue, investigation into the code paths led to the discovery we are not always handling the return codes from couchstore within the saveDocs method. As such, fix this so we are protected from potential failures. Change-Id: If378efb1f89d2c8b3a169b5ac0265e8214a1dae3 Reviewed-on: http://review.couchbase.org/95371 Well-Formed: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 9993d01 commit 3c0339f

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

engines/ep/src/couch-kvstore/couch-kvstore.cc

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,9 @@ static int readDocInfos(Db *db, DocInfo *docinfo, void *ctx) {
19411941
if (ctx == nullptr) {
19421942
throw std::invalid_argument("readDocInfos: ctx must be non-NULL");
19431943
}
1944+
if (!docinfo) {
1945+
throw std::invalid_argument("readDocInfos: docInfo must be non-NULL");
1946+
}
19441947
kvstats_ctx* cbCtx = static_cast<kvstats_ctx*>(ctx);
19451948
if(docinfo) {
19461949
// An item exists in the VB DB file.
@@ -1994,12 +1997,22 @@ couchstore_error_t CouchKVStore::saveDocs(uint16_t vbid,
19941997
ids[idx], configuration.shouldPersistDocNamespace());
19951998
kvctx.keyStats[key] = false;
19961999
}
1997-
couchstore_docinfos_by_id(db,
1998-
ids.data(),
1999-
(unsigned)ids.size(),
2000-
0,
2001-
readDocInfos,
2002-
&kvctx);
2000+
errCode = couchstore_docinfos_by_id(db,
2001+
ids.data(),
2002+
(unsigned)ids.size(),
2003+
0,
2004+
readDocInfos,
2005+
&kvctx);
2006+
if (errCode != COUCHSTORE_SUCCESS) {
2007+
logger.log(EXTENSION_LOG_WARNING,
2008+
"CouchKVStore::saveDocs: couchstore_docinfos_by_id "
2009+
"error:%s [%s], vb:%" PRIu16 ", numdocs:%" PRIu64,
2010+
couchstore_strerror(errCode),
2011+
couchkvstore_strerrno(db, errCode).c_str(),
2012+
vbid,
2013+
uint64_t(docs.size()));
2014+
return errCode;
2015+
}
20032016

20042017
auto cs_begin = ProcessClock::now();
20052018
uint64_t flags = COMPRESS_DOC_BODIES | COUCHSTORE_SEQUENCE_AS_IS;
@@ -2053,7 +2066,15 @@ couchstore_error_t CouchKVStore::saveDocs(uint16_t vbid,
20532066
st.batchSize.add(docs.size());
20542067

20552068
// retrieve storage system stats for file fragmentation computation
2056-
couchstore_db_info(db, &info);
2069+
errCode = couchstore_db_info(db, &info);
2070+
if (errCode) {
2071+
logger.log(
2072+
EXTENSION_LOG_WARNING,
2073+
"CouchKVStore::saveDocs: couchstore_db_info error:%s [%s]",
2074+
couchstore_strerror(errCode),
2075+
couchkvstore_strerrno(db, errCode).c_str());
2076+
return errCode;
2077+
}
20572078
cachedSpaceUsed[vbid] = info.space_used;
20582079
cachedFileSize[vbid] = info.file_size;
20592080
cachedDeleteCount[vbid] = info.deleted_count;

engines/ep/tests/module_tests/ep_unit_tests_main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "programs/engine_testapp/mock_server.h"
2323

2424
#include <getopt.h>
25-
#include <gtest/gtest.h>
25+
#include <gmock/gmock.h>
2626
#include <logger/logger.h>
2727

2828
#include "configuration.h"
@@ -67,6 +67,6 @@ int main(int argc, char **argv) {
6767
// Need to initialize ep_real_time and friends.
6868
initialize_time_functions(get_mock_server_api()->core);
6969

70-
::testing::InitGoogleTest(&argc, argv);
70+
::testing::InitGoogleMock(&argc, argv);
7171
return RUN_ALL_TESTS();
7272
}

engines/ep/tests/module_tests/kvstore_test.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,48 @@ TEST_F(CouchKVStoreErrorInjectionTest, closeDB_close_file) {
10791079
}
10801080
}
10811081

1082+
/**
1083+
* Injects error during CouchKVStore::saveDocs/couchstore_docinfos_by_id
1084+
*/
1085+
TEST_F(CouchKVStoreErrorInjectionTest, savedocs_doc_infos_by_id) {
1086+
// Insert some items into the B-Tree
1087+
generate_items(6);
1088+
CustomCallback<TransactionContext, mutation_result> set_callback;
1089+
1090+
for (const auto item : items) {
1091+
kvstore->begin(std::make_unique<TransactionContext>());
1092+
kvstore->set(item, set_callback);
1093+
kvstore->commit(nullptr /*no collections manifest*/);
1094+
}
1095+
1096+
{
1097+
generate_items(1);
1098+
CustomCallback<TransactionContext, mutation_result> set_callback;
1099+
1100+
kvstore->begin(std::make_unique<TransactionContext>());
1101+
kvstore->set(items.front(), set_callback);
1102+
{
1103+
/* Establish Logger expectation */
1104+
EXPECT_CALL(logger, mlog(_, _)).Times(AnyNumber());
1105+
EXPECT_CALL(
1106+
logger,
1107+
mlog(Ge(EXTENSION_LOG_WARNING), VCE(COUCHSTORE_ERROR_READ)))
1108+
.Times(1)
1109+
.RetiresOnSaturation();
1110+
1111+
/* Establish FileOps expectation */
1112+
EXPECT_CALL(ops, pread(_, _, _, _, _))
1113+
.WillOnce(Return(COUCHSTORE_ERROR_READ))
1114+
.RetiresOnSaturation();
1115+
EXPECT_CALL(ops, pread(_, _, _, _, _))
1116+
.Times(4)
1117+
.RetiresOnSaturation();
1118+
1119+
kvstore->commit(nullptr /*no collections manifest*/);
1120+
}
1121+
}
1122+
}
1123+
10821124
/**
10831125
* Verify the failed compaction statistic is accurate.
10841126
*/

0 commit comments

Comments
 (0)