void AsciiSerializedRequest::prepareImpl(const McRequest& request, McOperation<mc_op_delete>) { auto len = snprintf(printBuffer_, kMaxBufferLength, " %u\r\n", request.exptime()); assert(len > 0 && len < kMaxBufferLength); addStrings("delete ", request.fullKey(), folly::StringPiece(printBuffer_, static_cast<size_t>(len))); }
TypedThriftMessage<cpp2::McTouchRequest> convertToTyped( const McRequest& req, McOperation<mc_op_touch>) { TypedThriftMessage<cpp2::McTouchRequest> treq; treq->key = req.key().clone(); if (req.exptime() != 0) { treq->__isset.exptime = true; treq->exptime = req.exptime(); } return treq; }
void AsciiSerializedRequest::prepareImpl(const McRequest& request, McOperation<mc_op_cas>) { auto value = request.valueRangeSlow(); auto len = snprintf(printBuffer_, kMaxBufferLength, " %lu %u %zd %lu\r\n", request.flags(), request.exptime(), value.size(), request.cas()); assert(len > 0 && len < kMaxBufferLength); addStrings("cas ", request.fullKey(), folly::StringPiece(printBuffer_, static_cast<size_t>(len)), value, "\r\n"); }
TEST(McServerAsciiParserHarness, shutdown) { TestRunner() .expectNext(McOperation<mc_op_shutdown>(), McRequest()) .run("shutdown\r\n") .run("shutdown \r\n"); // With delay. McRequest r; r.setNumber(10); TestRunner() .expectNext(McOperation<mc_op_shutdown>(), std::move(r)) .run("shutdown 10\r\n") .run("shutdown 10 \r\n"); }
void AsciiSerializedRequest::prepareImpl(const McRequest& request, McOperation<mc_op_flushall>) { auto len = snprintf(printBuffer_, kMaxBufferLength, " %u\r\n", request.number()); addStrings("flush_all", folly::StringPiece(printBuffer_, static_cast<size_t>(len))); }
TypedThriftMessage<cpp2::McLeaseSetRequest> convertToTyped( const McRequest& req, McOperation<mc_op_lease_set>) { TypedThriftMessage<cpp2::McLeaseSetRequest> treq; treq->leaseToken = req.leaseToken(); updateLikeCommon(treq, req); return treq; }
TypedThriftMessage<cpp2::McCasRequest> convertToTyped(const McRequest& req, McOperation<mc_op_cas>) { TypedThriftMessage<cpp2::McCasRequest> treq; treq->casToken = req.cas(); updateLikeCommon(treq, req); return treq; }
MockMc::Item::Item(const McRequest& req) : value(req.value().clone()), exptime(req.exptime() > 0 ? req.exptime() + time(nullptr) : 0), flags(req.flags()) { }
void AsciiSerializedRequest::prepareImpl(const McRequest& request, McOperation<mc_op_lease_get>) { addStrings("lease-get ", request.fullKey(), "\r\n"); }
McRequest umbrellaParseRequest(const folly::IOBuf& source, const uint8_t* header, size_t nheader, const uint8_t* body, size_t nbody, mc_op_t& opOut, uint64_t& reqidOut) { McRequest req; opOut = mc_op_unknown; reqidOut = 0; auto msg = reinterpret_cast<const entry_list_msg_t*>(header); size_t nentries = folly::Endian::big((uint16_t)msg->nentries); if (reinterpret_cast<const uint8_t*>(&msg->entries[nentries]) != header + nheader) { throw std::runtime_error("Invalid number of entries"); } for (size_t i = 0; i < nentries; ++i) { auto& entry = msg->entries[i]; size_t tag = folly::Endian::big((uint16_t)entry.tag); size_t val = folly::Endian::big((uint64_t)entry.data.val); switch (tag) { case msg_op: if (val >= UM_NOPS) { throw std::runtime_error("op out of range"); } opOut = static_cast<mc_op_t>(umbrella_op_to_mc[val]); break; case msg_reqid: if (val == 0) { throw std::runtime_error("invalid reqid"); } reqidOut = val; break; case msg_flags: req.setFlags(val); break; case msg_exptime: req.setExptime(val); break; case msg_delta: req.setDelta(val); break; case msg_cas: req.setCas(val); break; case msg_lease_id: req.setLeaseToken(val); break; case msg_key: if (!req.setKeyFrom( source, body + folly::Endian::big((uint32_t)entry.data.str.offset), folly::Endian::big((uint32_t)entry.data.str.len) - 1)) { throw std::runtime_error("Key: invalid offset/length"); } break; case msg_value: if (!req.setValueFrom( source, body + folly::Endian::big((uint32_t)entry.data.str.offset), folly::Endian::big((uint32_t)entry.data.str.len) - 1)) { throw std::runtime_error("Value: invalid offset/length"); } break; #ifndef LIBMC_FBTRACE_DISABLE case msg_fbtrace: { auto off = folly::Endian::big((uint32_t)entry.data.str.offset); auto len = folly::Endian::big((uint32_t)entry.data.str.len) - 1; if (len > FBTRACE_METADATA_SZ) { throw std::runtime_error("Fbtrace metadata too large"); } if (off + len > nbody || off + len < off) { throw std::runtime_error("Fbtrace metadata field invalid"); } auto fbtraceInfo = new_mc_fbtrace_info(0); memcpy(fbtraceInfo->metadata, body + off, len); req.setFbtraceInfo(fbtraceInfo); break; } #endif default: /* Ignore unknown tags silently */ break; } } if (opOut == mc_op_unknown) { throw std::runtime_error("Request missing operation"); } if (!reqidOut) { throw std::runtime_error("Request missing reqid"); } return req; }
multiTokenOpTest(McOperation<mc_op_exec>(), "exec"); multiTokenOpTest(McOperation<mc_op_exec>(), "admin"); } TEST(McServerAsciiParserHarness, delete) { TestRunner() .expectNext(McOperation<mc_op_delete>(), McRequest("test:stepan:1")) .run("delete test:stepan:1\r\n") .run("delete test:stepan:1 \r\n"); TestRunner() .expectNext(McOperation<mc_op_delete>(), McRequest("test:stepan:1"), true) .run("delete test:stepan:1 noreply\r\n") .run("delete test:stepan:1 noreply \r\n"); McRequest r("test:stepan:1"); r.setExptime(-10); TestRunner() .expectNext(McOperation<mc_op_delete>(), r.clone()) .run("delete test:stepan:1 -10\r\n") .run("delete test:stepan:1 -10 \r\n"); r.setExptime(1234123); TestRunner() .expectNext(McOperation<mc_op_delete>(), r.clone()) .run("delete test:stepan:1 1234123\r\n") .run("delete test:stepan:1 1234123 \r\n"); TestRunner() .expectNext(McOperation<mc_op_delete>(), r.clone(), true) .run("delete test:stepan:1 1234123 noreply\r\n") .run("delete test:stepan:1 1234123 noreply \r\n");