Skip to content

Commit 43bc123

Browse files
mattcarabinedaverigby
authored andcommitted
MB-28850: Fix regression in append stat tracking
- Append operations are supposed to be tracked under cmd_set. - A refactoring of the append state machine caused this stat to not be incremented after successful appends. - This commit ensures that the stat is appending at the correct stage of the append operation state machine. - Added unit tests to ensure that any future regression in append stat tracking is caught. Change-Id: I3369479cbf4a34f151c9252d2ccfd68dd82777fd Reviewed-on: http://review.couchbase.org/91441 Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]> Reviewed-on: http://review.couchbase.org/91515 Well-Formed: Build Bot <[email protected]> Reviewed-by: Matt Carabine <[email protected]> Reviewed-by: Tim Bradgate <[email protected]>
1 parent d4c951f commit 43bc123

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

daemon/protocol/mcbp/appendprepend_context.cc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,11 @@ ENGINE_ERROR_CODE AppendPrependCommandContext::step() {
4040
ret = reset();
4141
break;
4242
case State::Done:
43+
SLAB_INCR(&connection, cmd_set);
4344
return ENGINE_SUCCESS;
4445
}
4546
} while (ret == ENGINE_SUCCESS);
4647

47-
if (ret != ENGINE_EWOULDBLOCK) {
48-
SLAB_INCR(&connection, cmd_set);
49-
}
50-
5148
if (ret == ENGINE_KEY_ENOENT) {
5249
// for some reason the return code for no key is not stored so we need
5350
// to remap that error code..

tests/testapp/testapp_stats.cc

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,70 @@ TEST_P(StatsTest, Test_MB_17815) {
135135
EXPECT_EQ(1, count->valueint);
136136
}
137137

138+
/**
139+
* MB-17815: The cmd_set stat is incremented multiple times if the underlying
140+
* engine returns EWOULDBLOCK (which would happen for all operations when
141+
* the underlying engine is operating in full eviction mode and the document
142+
* isn't resident). This test is specfically testing this error case with
143+
* append (due to MB-28850) rather than the other MB-17815 test which tests
144+
* Add.
145+
*/
146+
TEST_P(StatsTest, Test_MB_17815_Append) {
147+
MemcachedConnection& conn = getConnection();
148+
149+
auto stats = conn.stats("");
150+
auto* count = cJSON_GetObjectItem(stats.get(), "cmd_set");
151+
ASSERT_NE(nullptr, count);
152+
EXPECT_EQ(cJSON_Number, count->type);
153+
EXPECT_EQ(0, count->valueint);
154+
155+
// Allow first SET to succeed and then return EWOULDBLOCK for
156+
// the Append (2nd op). Set all other operations to fail too since we
157+
// do not expect any further operations.
158+
conn.configureEwouldBlockEngine(EWBEngineMode::Sequence,
159+
ENGINE_EWOULDBLOCK,
160+
0xfffffffe /* Set to 0b11 111 110 */);
161+
162+
// Set a document
163+
Document doc;
164+
doc.info.cas = mcbp::cas::Wildcard;
165+
doc.info.datatype = cb::mcbp::Datatype::JSON;
166+
doc.info.flags = 0xcaffee;
167+
doc.info.id = name;
168+
doc.value.assign(10, static_cast<uint8_t>('x'));
169+
conn.mutate(doc, 0, MutationType::Set);
170+
171+
// Now append to the same doc
172+
conn.mutate(doc, 0, MutationType::Append);
173+
stats = conn.stats("");
174+
count = cJSON_GetObjectItem(stats.get(), "cmd_set");
175+
ASSERT_NE(nullptr, count);
176+
EXPECT_EQ(cJSON_Number, count->type);
177+
EXPECT_EQ(2, count->valueint);
178+
}
179+
180+
TEST_P(StatsTest, TestAppend) {
181+
MemcachedConnection& conn = getConnection();
182+
183+
// Set a document
184+
Document doc;
185+
doc.info.cas = mcbp::cas::Wildcard;
186+
doc.info.datatype = cb::mcbp::Datatype::JSON;
187+
doc.info.flags = 0xcaffee;
188+
doc.info.id = name;
189+
doc.value.assign(10, static_cast<uint8_t>('x'));
190+
conn.mutate(doc, 0, MutationType::Set);
191+
192+
// Send 10 appends, this should increase the `cmd_set` stat by 10
193+
for (int i = 0; i < 10; i++) {
194+
conn.mutate(doc, 0, MutationType::Append);
195+
}
196+
auto stats = conn.stats("");
197+
cJSON* cmd_set = cJSON_GetObjectItem(stats.get(), "cmd_set");
198+
// In total we expect 11 sets, since there was the initial set
199+
// and then 10 appends
200+
EXPECT_EQ(11, cmd_set->valueint);
201+
}
138202

139203
TEST_P(StatsTest, TestSettings) {
140204
MemcachedConnection& conn = getConnection();

0 commit comments

Comments
 (0)