1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 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 #pragma once
18 
19 #include "conn_notifier.h"
20 #include "connhandler.h"
21 #include "dcp/dcpconnmap.h"
22 
23 /*
24  * Mock of the DcpConnMap class.  Wraps the real DcpConnMap, but exposes
25  * normally protected methods publically for test purposes.
26  */
27 class MockDcpConnMap : public DcpConnMap {
28 public:
MockDcpConnMap(EventuallyPersistentEngine& theEngine)29     MockDcpConnMap(EventuallyPersistentEngine& theEngine)
30         : DcpConnMap(theEngine) {
31     }
32 
getNumberOfDeadConnections()33     size_t getNumberOfDeadConnections() {
34         return deadConnections.size();
35     }
36 
getPendingNotifications()37     AtomicQueue<std::weak_ptr<ConnHandler>>& getPendingNotifications() {
38         return pendingNotifications;
39     }
40 
initialize()41     void initialize() {
42         connNotifier_ = std::make_shared<ConnNotifier>(*this);
43         // We do not create a ConnNotifierCallback task
44         // We do not create a ConnManager task
45         // The ConnNotifier is deleted in the DcpConnMap
46         // destructor
47     }
48 
addConn(const void* cookie, std::shared_ptr<ConnHandler> conn)49     void addConn(const void* cookie, std::shared_ptr<ConnHandler> conn) {
50         LockHolder lh(connsLock);
51         map_[cookie] = conn;
52     }
53 
removeConn(const void* cookie)54     bool removeConn(const void* cookie) {
55         LockHolder lh(connsLock);
56         auto itr = map_.find(cookie);
57         if (itr != map_.end()) {
58             map_.erase(itr);
59             return true;
60         }
61         return false;
62     }
63 
64     /// return if the named handler exists for the vbid in the vbConns structure
doesConnHandlerExist(Vbid vbid, const std::string& name) const65     bool doesConnHandlerExist(Vbid vbid, const std::string& name) const {
66         const auto& list = vbConns[vbid.get()];
67         return std::find_if(
68                        list.begin(),
69                        list.end(),
70                        [&name](const std::weak_ptr<ConnHandler>& c) -> bool {
71                            auto p = c.lock();
72                            return p && p->getName() == name;
73                        }) != list.end();
74     }
75 
76 protected:
77     /**
78      * @param engine The engine
79      * @param cookie The cookie that identifies the connection
80      * @param connName The name that identifies the connection
81      * @return a shared instance of MockDcpConsumer
82      */
83     std::shared_ptr<DcpConsumer> makeConsumer(
84             EventuallyPersistentEngine& engine,
85             const void* cookie,
86             const std::string& connName,
87             const std::string& consumerName) const override;
88 };
89