Apache Mesos
zookeeper.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. 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 #ifndef __TESTS_ZOOKEEPER_HPP__
18 #define __TESTS_ZOOKEEPER_HPP__
19 
20 #include <stdint.h>
21 
22 #include <condition_variable>
23 #include <mutex>
24 #include <queue>
25 
26 #include <gtest/gtest.h>
27 
28 #include <stout/duration.hpp>
29 
31 
32 namespace mesos {
33 namespace internal {
34 namespace tests {
35 
36 // Helper for invoking ZooKeeper::get(path, ...) in order to check the
37 // data stored at a specified znode path.
38 inline ::testing::AssertionResult AssertZKGet(
39  const char* expectedExpr,
40  const char* zkExpr,
41  const char* pathExpr,
42  const std::string& expected,
43  ZooKeeper* zk,
44  const std::string& path)
45 {
46  std::string result;
47  int code = zk->get(path, false, &result, nullptr);
48  if (code == ZOK) {
49  if (expected == result) {
50  return ::testing::AssertionSuccess();
51  } else {
52  return ::testing::AssertionFailure()
53  << "Expected data at znode '" << pathExpr << "' "
54  << "to be '" << expected << "', but actually '" << result << "'";
55  }
56  } else {
57  return ::testing::AssertionFailure()
58  << "(" << zkExpr << ").get(" << pathExpr << ", ...): "
59  << zk->message(code);
60  }
61 }
62 
63 #define ASSERT_ZK_GET(expected, zk, path) \
64  ASSERT_PRED_FORMAT3(mesos::internal::tests::AssertZKGet, expected, zk, path)
65 
66 
67 // A fixture for tests that need to interact with a ZooKeeper server
68 // ensemble. Tests can access the in process ZooKeeperTestServer via
69 // the variable 'server'. This test fixture ensures the server is
70 // started before each test and shutdown after it so that each test is
71 // presented with a ZooKeeper ensemble with no data or watches.
72 class ZooKeeperTest : public ::testing::Test
73 {
74 public:
75  // A watcher that is useful to install in a ZooKeeper client for
76  // tests. Allows easy blocking on expected events.
77  class TestWatcher : public Watcher
78  {
79  public:
80  // Encapsulates all the state of a ZooKeeper watcher event.
81  struct Event {
82  Event(int _type, int _state, const std::string& _path)
83  : type(_type), state(_state), path(_path) {}
84  const int type;
85  const int state;
86  const std::string path;
87  };
88 
89  TestWatcher() = default;
90  ~TestWatcher() override = default;
91 
92  void process(
93  int type,
94  int state,
95  int64_t sessionId,
96  const std::string& path) override;
97 
98  // Blocks until the session event of the given state fires.
99  void awaitSessionEvent(int state);
100 
101  // Blocks until a node appears at the given path.
102  void awaitCreated(const std::string& path);
103 
104  // Blocks until an event is fired matching the given predicate.
105  Event awaitEvent(const lambda::function<bool(Event)>& matches);
106 
107  // Blocks until an event is fired.
108  Event awaitEvent();
109 
110  private:
111  std::queue<Event> events;
112  std::mutex mutex;
113  std::condition_variable cond;
114  };
115 
116  static void SetUpTestCase();
117 
118 protected:
120  ~ZooKeeperTest() override { delete server; }
121 
122  void SetUp() override;
123 
124  // A very long session timeout that simulates no timeout for test cases.
125  static const Duration NO_TIMEOUT;
126 
127  // TODO(benh): Share the same ZooKeeperTestServer across all tests?
129 };
130 
131 } // namespace tests {
132 } // namespace internal {
133 } // namespace mesos {
134 
135 #endif // __ZOOKEEPER_TEST_HPP__
Definition: path.hpp:29
const int type
Definition: zookeeper.hpp:84
Definition: zookeeper.hpp:115
Event(int _type, int _state, const std::string &_path)
Definition: zookeeper.hpp:82
Definition: duration.hpp:32
const int state
Definition: zookeeper.hpp:85
void process(int type, int state, int64_t sessionId, const std::string &path) override
inline::testing::AssertionResult AssertZKGet(const char *expectedExpr, const char *zkExpr, const char *pathExpr, const std::string &expected, ZooKeeper *zk, const std::string &path)
Definition: zookeeper.hpp:38
This interface specifies the public interface an event handler class must implement.
Definition: zookeeper.hpp:59
~ZooKeeperTest() override
Definition: zookeeper.hpp:120
ZooKeeperTest()
Definition: zookeeper.hpp:119
int get(const std::string &path, bool watch, std::string *result, Stat *stat)
gets the data associated with a node synchronously.
ZooKeeperTestServer * server
Definition: zookeeper.hpp:128
Definition: agent.hpp:25
static const Duration NO_TIMEOUT
Definition: zookeeper.hpp:125
const std::string path
Definition: zookeeper.hpp:86
Definition: attributes.hpp:24
Definition: zookeeper_test_server.hpp:36
Definition: zookeeper.hpp:72
std::string message(int code) const
return a message describing the return code.