1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2015 Couchbase, Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 /*
19  *                "ewouldblock_engine"
20  *
21  * The "ewouldblock_engine" allows one to test how memcached responds when the
22  * engine returns EWOULDBLOCK instead of the correct response.
23  */
24 #pragma once
25 
26 #include "config.h"
27 
28 #include <memcached/protocol_binary.h>
29 
30 using request_ewouldblock_ctl = protocol_binary_request_ewb_ctl;
31 using response_ewouldblock_ctl = protocol_binary_response_ewb_ctl;
32 
33 // The mode the engine is currently operating in. Determines when it will
34 // inject EWOULDBLOCK instead of the real return code.
35 enum class EWBEngineMode : uint32_t {
36     // Make the next_N calls into engine return {inject_error}. N specified
37     // by the {value} field.
38     Next_N = 0,
39 
40     // Randomly return {inject_error}. Chance to return {inject_error} is
41     // specified as an integer percentage (1,100) in the {value} field.
42     Random = 1,
43 
44     // The first call to a given function from each connection will return
45     // {inject_error}, with the next (and subsequent) calls to the *same*
46     // function operating normally. Calling a different function will reset
47     // back to failing again.  In other words, return {inject_error} if the
48     // previous function was not this one.
49     First = 2,
50 
51     // Make the next N calls return a sequence of either their normal value or
52     // the injected error code. The sequence can be up to 32 elements long.
53     Sequence = 3,
54 
55     // Simulate CAS mismatch - make the next N store operations return
56     // KEY_EEXISTS. N specified by the {value} field.
57     CasMismatch = 4,
58 
59     // Increment the cluster map sequence number. Value and inject_error is
60     // ignored for this opcode
61     IncrementClusterMapRevno = 5,
62 
63     // Make a single call into engine and return {inject_error}.  In addition
64     // do not add the operation to the processing queue and so a
65     // notify_io_complete is never sent.
66     No_Notify = 6,
67 
68     // Suspend a cookie with the provided id and return ENGINE_EWOULDBLOCK.
69     // The connection must be resumed with a call to Resume
70     Suspend = 7,
71 
72     // Resume a cookie with the provided id
73     Resume = 8,
74 
75     // Next time the connection invokes a call we'll start monitoring a file
76     // for existence, and when the file goes away we'll notify the connection
77     // with the {inject_error}.
78     // The file to monitor is specified in the key for the packet.
79     // This seems like an odd interface to have, but it is needed to be able
80     // to test what happens with clients that is working inside the engine
81     // while a bucket is deleted. Given that we're not instructing the
82     // ewouldblock engine on a special channel there is no way to send
83     // commmands to the engine whlie it is being deleted ;-)
84     BlockMonitorFile = 9,
85 
86     // Set the CAS for an item.
87     // Requires the CAS of the item. Bear in mind that we're limited to
88     // 32 bits.
89     SetItemCas = 10
90 };
91