Skip to content

Commit 92d00b1

Browse files
BenHuddlestondaverigby
authored andcommitted
MB-33637: Fix memcached testapp ChangeVerbosity LoggingTest
This test is currently flawed for multiple reasons. 1) When run in non-embedded mode (every CV run) the test looks will always pass because the cb::logger::checkLogLevels() call will look in the registry belonging to the testapp process and not the memcached process. This means that it will find no loggers to check the verbosity of, and will always return true. 2) The test log levels are the wrong way around. 3) The test is racey. We might attempt to shut down the memcached server before the thread that changes verbosity completes execution. This thread will segfault when it logs if this is the case. Fix this test by: a) Creating an EWB command that returns SUCCESS if the log levels are the correct value. b) Fixing the log level mapping. c) Runing the verbosity change in the memcached worker thread. It's a quick operation that will only block if we are registering or unregistered loggers (creating/destroying buckets/DCP connections). Verbosity changing is also very infrequently used. Change-Id: I1b9d36217e7108b44663b8f5bcf013ceae6a4050 Reviewed-on: http://review.couchbase.org/107289 Tested-by: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent e550190 commit 92d00b1

File tree

4 files changed

+49
-14
lines changed

4 files changed

+49
-14
lines changed

daemon/memcached.cc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ void associate_initial_bucket(Connection& connection) {
264264
}
265265
}
266266

267-
static void populate_log_level(void*) {
267+
static void populate_log_level() {
268268
const auto val = settings.getLogLevel();
269269

270270
// Log the verbosity value set by the user and not the log level as they
@@ -278,8 +278,6 @@ void perform_callbacks(ENGINE_EVENT_TYPE type,
278278
const void *data,
279279
const void *void_cookie)
280280
{
281-
cb_thread_t tid;
282-
283281
switch (type) {
284282
/*
285283
* The following events operates on a connection which is passed in
@@ -316,11 +314,12 @@ void perform_callbacks(ENGINE_EVENT_TYPE type,
316314
}
317315

318316
if (service_online) {
319-
if (cb_create_thread(&tid, populate_log_level, nullptr, 1) == -1) {
320-
LOG_WARNING(
321-
"Failed to create thread to notify engines about "
322-
"changing log level");
323-
}
317+
// MB-33637: Make the verbosity change in the calling thread.
318+
// This should be a relatively quick operation as we only block if
319+
// we are registering or unregistering new loggers. It also prevents
320+
// a race condition on shutdown where we could attempt to log
321+
// something but the logger has already been destroyed.
322+
populate_log_level();
324323
}
325324
break;
326325

engines/ewouldblock_engine/ewouldblock_engine.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,9 @@ class EWB_Engine : public EngineIface, public DcpIface {
618618

619619
case EWBEngineMode::SetItemCas:
620620
return setItemCas(cookie, key, value, response);
621+
622+
case EWBEngineMode::CheckLogLevels:
623+
return checkLogLevels(cookie, value, response);
621624
}
622625

623626
if (new_mode == nullptr) {
@@ -1012,6 +1015,10 @@ class EWB_Engine : public EngineIface, public DcpIface {
10121015
uint32_t cas,
10131016
const AddResponseFn& response);
10141017

1018+
ENGINE_ERROR_CODE checkLogLevels(const void* cookie,
1019+
uint32_t value,
1020+
const AddResponseFn& response);
1021+
10151022
private:
10161023
// Shared state between the main thread of execution and the background
10171024
// thread processing pending io ops.
@@ -1988,6 +1995,25 @@ ENGINE_ERROR_CODE EWB_Engine::setItemCas(const void* cookie,
19881995
return ENGINE_SUCCESS;
19891996
}
19901997

1998+
ENGINE_ERROR_CODE EWB_Engine::checkLogLevels(const void* cookie,
1999+
uint32_t value,
2000+
const AddResponseFn& response) {
2001+
auto level = spdlog::level::level_enum(value);
2002+
auto rsp = cb::logger::checkLogLevels(level);
2003+
2004+
response(nullptr,
2005+
0,
2006+
nullptr,
2007+
0,
2008+
nullptr,
2009+
0,
2010+
PROTOCOL_BINARY_RAW_BYTES,
2011+
rsp ? cb::mcbp::Status::Success : cb::mcbp::Status::Einval,
2012+
0,
2013+
cookie);
2014+
return ENGINE_SUCCESS;
2015+
}
2016+
19912017
cb::engine_errc EWB_Engine::set_collection_manifest(
19922018
gsl::not_null<const void*> cookie, cb::const_char_buffer json) {
19932019
return real_engine->set_collection_manifest(cookie, json);

engines/ewouldblock_engine/ewouldblock_engine.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,10 @@ enum class EWBEngineMode : uint32_t {
8181
// Set the CAS for an item.
8282
// Requires the CAS of the item. Bear in mind that we're limited to
8383
// 32 bits.
84-
SetItemCas = 10
84+
SetItemCas = 10,
85+
86+
// Make a single call to cb::logger::check_levels and return the result.
87+
// This allows us to verify that all of the registered logger instances are
88+
// set to the correct level.
89+
CheckLogLevels = 11,
8590
};

tests/testapp/testapp_logging.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class LoggingTest : public TestappTest,
3636

3737
// Fail this test if the connection does not return a successful
3838
// response
39-
EXPECT_TRUE(rsp.isSuccess());
39+
ASSERT_TRUE(rsp.isSuccess());
4040
}
4141
};
4242

@@ -46,17 +46,22 @@ TEST_P(LoggingTest, ChangeVerbosity) {
4646
spdlog::level::level_enum level;
4747
switch (GetParam()) {
4848
case 0:
49-
level = spdlog::level::trace;
49+
level = spdlog::level::info;
5050
break;
5151
case 1:
5252
level = spdlog::level::debug;
5353
break;
54-
default: /* We default to 2 if a greater number is specified */
55-
level = spdlog::level::info;
54+
default:
55+
level = spdlog::level::trace;
5656
break;
5757
}
5858

59-
EXPECT_TRUE(cb::logger::checkLogLevels(level));
59+
// The configure function will check the response and fail the test if not
60+
// ENGINE_SUCCESS.
61+
ewouldblock_engine_configure(ENGINE_ERROR_CODE::ENGINE_SUCCESS,
62+
EWBEngineMode::CheckLogLevels,
63+
level,
64+
"key");
6065
}
6166

6267
// Test with verbosity values 0, 1, 2

0 commit comments

Comments
 (0)