You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2013/05/26 18:57:35 UTC
[10/28] Refactored MesosTest/MesosClusterTest into a generic fixture
for launching in-memory Mesos clusters and updated all tests appropriately.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/utils.hpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.hpp b/src/tests/utils.hpp
index 60e4678..3b80933 100644
--- a/src/tests/utils.hpp
+++ b/src/tests/utils.hpp
@@ -19,76 +19,16 @@
#ifndef __TESTS_UTILS_HPP__
#define __TESTS_UTILS_HPP__
-#include <unistd.h> // For usleep.
+#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include <fstream>
-#include <map>
#include <string>
-#include <mesos/executor.hpp>
-#include <mesos/scheduler.hpp>
-
-#include <process/future.hpp>
-#include <process/gmock.hpp>
-#include <process/gtest.hpp>
-#include <process/http.hpp>
-#include <process/process.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/gtest.hpp>
-#include <stout/lambda.hpp>
-#include <stout/nothing.hpp>
#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/path.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-#include <stout/uuid.hpp>
-
-#include "common/resources.hpp"
-#include "common/type_utils.hpp"
-
-#ifdef __linux__
-#include "linux/cgroups.hpp"
-#endif
-
-#include "logging/logging.hpp"
-
-#include "master/allocator.hpp"
-#include "master/drf_sorter.hpp"
-#include "master/hierarchical_allocator_process.hpp"
-#include "master/master.hpp"
-
-#include "messages/messages.hpp"
-
-#ifdef __linux__
-#include "slave/cgroups_isolator.hpp"
-#endif
-#include "slave/isolator.hpp"
-#include "slave/reaper.hpp"
-#include "slave/slave.hpp"
-#include "slave/state.hpp"
-
-#include "tests/cluster.hpp"
-#include "tests/environment.hpp"
-#include "tests/flags.hpp"
-#include "tests/isolator.hpp"
namespace mesos {
namespace internal {
namespace tests {
-#ifdef __linux__
-// Cgroups hierarchy used by the cgroups related tests.
-const static std::string TEST_CGROUPS_HIERARCHY = "/tmp/mesos_test_cgroup";
-
-// Name of the root cgroup used by the cgroups related tests.
-const static std::string TEST_CGROUPS_ROOT = "mesos_test";
-#endif
-
-
// Test fixture for creating a temporary directory for each test.
class TemporaryDirectoryTest : public ::testing::Test
{
@@ -101,671 +41,6 @@ private:
Option<std::string> sandbox;
};
-
-// Test fixture to setup mesos configuration for tests.
-// This fixture creates a new temporary working directory for each test and
-// deletes it when a test finishes. It also supports setting slave resources.
-// TODO(vinod): Make this fixture more generic to provide a basic set of
-// setup abstractions for tests.
-class MesosTest : public ::testing::Test
-{
-protected:
- virtual void SetUp()
- {
- // Create a temporary directory for the test.
- Try<std::string> directory = environment->mkdtemp();
-
- CHECK(directory.isSome())
- << "Failed to create temporary directory: " << directory.error();
-
- slaveFlags.work_dir = directory.get();
- slaveFlags.launcher_dir = path::join(tests::flags.build_dir, "src");
-
- // For locating killtree.sh.
- os::setenv("MESOS_SOURCE_DIR", tests::flags.source_dir);
-
- setSlaveResources("cpus:2;mem:1024;disk:1024;ports:[31000-32000]");
- }
-
- virtual void TearDown()
- {
- os::rmdir(slaveFlags.work_dir);
-
- os::unsetenv("MESOS_SOURCE_DIR");
- }
-
- void setSlaveResources(const std::string& resources)
- {
- slaveFlags.resources = Option<std::string>::some(resources);
- }
-
- slave::Flags slaveFlags;
-};
-
-
-class MesosClusterTest : public ::testing::Test
-{
-protected:
- virtual void SetUp()
- {
- // Create a temporary directory for the test.
- Try<std::string> directory = environment->mkdtemp();
-
- CHECK(directory.isSome())
- << "Failed to create temporary directory: " << directory.error();
-
- cluster.slaves.flags.work_dir = directory.get();
- cluster.slaves.flags.launcher_dir =
- path::join(tests::flags.build_dir, "src");
-
- // For locating killtree.sh.
- os::setenv("MESOS_SOURCE_DIR", tests::flags.source_dir);
-
- cluster.slaves.flags.resources =
- Option<std::string>("cpus:2;mem:1024;disk:1024;ports:[31000-32000]");
- }
-
- virtual void TearDown()
- {
- os::rmdir(cluster.slaves.flags.work_dir);
-
- os::unsetenv("MESOS_SOURCE_DIR");
- }
-
- Cluster cluster;
-};
-
-
-
-template <typename T>
-class IsolatorTest : public MesosTest
-{};
-
-
-#ifdef __linux__
-template <>
-class IsolatorTest<slave::CgroupsIsolator> : public MesosTest
-{
-public:
- static void SetUpTestCase()
- {
- // Clean up the testing hierarchy, in case it wasn't cleaned up
- // properly from previous tests.
- AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
- }
-
- static void TearDownTestCase()
- {
- AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
- }
-
-protected:
- virtual void SetUp()
- {
- const std::string subsystems = "cpu,cpuacct,memory,freezer";
- Result<std::string> hierarchy_ = cgroups::hierarchy(subsystems);
- ASSERT_FALSE(hierarchy_.isError());
- if (hierarchy_.isNone()) {
- // Try to mount a hierarchy for testing.
- ASSERT_SOME(cgroups::mount(TEST_CGROUPS_HIERARCHY, subsystems))
- << "-------------------------------------------------------------\n"
- << "We cannot run any cgroups tests that require\n"
- << "a hierarchy with subsystems '" << subsystems << "'\n"
- << "because we failed to find an existing hierarchy\n"
- << "or create a new one. You can either remove all existing\n"
- << "hierarchies, or disable this test case\n"
- << "(i.e., --gtest_filter=-"
- << ::testing::UnitTest::GetInstance()
- ->current_test_info()
- ->test_case_name() << ".*).\n"
- << "-------------------------------------------------------------";
-
- hierarchy = TEST_CGROUPS_HIERARCHY;
- } else {
- hierarchy = hierarchy_.get();
- }
-
- MesosTest::SetUp();
-
- // Set slave's cgroup flags.
- slaveFlags.cgroups_hierarchy = hierarchy;
- slaveFlags.cgroups_root = TEST_CGROUPS_ROOT;
- }
-
- virtual void TearDown()
- {
- MesosTest::TearDown();
-
- Try<bool> exists = cgroups::exists(hierarchy, TEST_CGROUPS_ROOT);
- ASSERT_SOME(exists);
- if (exists.get()) {
- AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
- }
- }
-
-private:
- std::string hierarchy;
-};
-#endif
-
-
-// Macros to get/create (default) ExecutorInfos and FrameworkInfos.
-#define DEFAULT_EXECUTOR_INFO \
- ({ ExecutorInfo executor; \
- executor.mutable_executor_id()->set_value("default"); \
- executor.mutable_command()->set_value("exit 1"); \
- executor; })
-
-
-#define CREATE_EXECUTOR_INFO(executorId, command) \
- ({ ExecutorInfo executor; \
- executor.mutable_executor_id()->MergeFrom(executorId); \
- executor.mutable_command()->set_value(command); \
- executor; })
-
-
-#define DEFAULT_FRAMEWORK_INFO \
- ({ FrameworkInfo framework; \
- framework.set_name("default"); \
- framework; })
-
-
-#define DEFAULT_EXECUTOR_ID \
- DEFAULT_EXECUTOR_INFO.executor_id()
-
-
-inline TaskInfo createTask(
- const Offer& offer,
- const std::string& command,
- const std::string& name = "test-task",
- const std::string& id = UUID::random().toString())
-{
- TaskInfo task;
- task.set_name(name);
- task.mutable_task_id()->set_value(id);
- task.mutable_slave_id()->MergeFrom(offer.slave_id());
- task.mutable_resources()->MergeFrom(offer.resources());
- task.mutable_command()->set_value(command);
-
- return task;
-}
-
-
-// Definition of a mock Scheduler to be used in tests with gmock.
-class MockScheduler : public Scheduler
-{
-public:
- MOCK_METHOD3(registered, void(SchedulerDriver*,
- const FrameworkID&,
- const MasterInfo&));
- MOCK_METHOD2(reregistered, void(SchedulerDriver*, const MasterInfo&));
- MOCK_METHOD1(disconnected, void(SchedulerDriver*));
- MOCK_METHOD2(resourceOffers, void(SchedulerDriver*,
- const std::vector<Offer>&));
- MOCK_METHOD2(offerRescinded, void(SchedulerDriver*, const OfferID&));
- MOCK_METHOD2(statusUpdate, void(SchedulerDriver*, const TaskStatus&));
- MOCK_METHOD4(frameworkMessage, void(SchedulerDriver*,
- const ExecutorID&,
- const SlaveID&,
- const std::string&));
- MOCK_METHOD2(slaveLost, void(SchedulerDriver*, const SlaveID&));
- MOCK_METHOD4(executorLost, void(SchedulerDriver*,
- const ExecutorID&,
- const SlaveID&,
- int));
- MOCK_METHOD2(error, void(SchedulerDriver*, const std::string&));
-};
-
-// For use with a MockScheduler, for example:
-// EXPECT_CALL(sched, resourceOffers(_, _))
-// .WillOnce(LaunchTasks(TASKS, CPUS, MEM));
-// Launches up to TASKS no-op tasks, if possible,
-// each with CPUS cpus and MEM memory.
-ACTION_P3(LaunchTasks, tasks, cpus, mem)
-{
- SchedulerDriver* driver = arg0;
- std::vector<Offer> offers = arg1;
- int numTasks = tasks;
-
- int launched = 0;
- for (size_t i = 0; i < offers.size(); i++) {
- const Offer& offer = offers[i];
- double offeredCpus = 0;
- double offeredMem = 0;
-
- for (int j = 0; j < offer.resources_size(); j++) {
- const Resource& resource = offer.resources(j);
- if (resource.name() == "cpus" &&
- resource.type() == Value::SCALAR) {
- offeredCpus = resource.scalar().value();
- } else if (resource.name() == "mem" &&
- resource.type() == Value::SCALAR) {
- offeredMem = resource.scalar().value();
- }
- }
-
- int nextTaskId = 0;
- std::vector<TaskInfo> tasks;
-
- while (offeredCpus >= cpus && offeredMem >= mem && launched < numTasks) {
- TaskInfo task;
- task.set_name("TestTask");
- task.mutable_task_id()->set_value(stringify(nextTaskId++));
- task.mutable_slave_id()->MergeFrom(offer.slave_id());
-
- ExecutorInfo executor;
- executor.mutable_executor_id()->set_value("default");
- executor.mutable_command()->set_value(":");
- task.mutable_executor()->MergeFrom(executor);
-
- Resource* resource;
- resource = task.add_resources();
- resource->set_name("cpus");
- resource->set_type(Value::SCALAR);
- resource->mutable_scalar()->set_value(cpus);
-
- resource = task.add_resources();
- resource->set_name("mem");
- resource->set_type(Value::SCALAR);
- resource->mutable_scalar()->set_value(mem);
-
- tasks.push_back(task);
- launched++;
- offeredCpus -= cpus;
- offeredMem -= mem;
- }
-
- driver->launchTasks(offer.id(), tasks);
- }
-}
-
-
-// Like LaunchTasks, but decline the entire offer and
-// don't launch any tasks.
-ACTION(DeclineOffers)
-{
- SchedulerDriver* driver = arg0;
- std::vector<Offer> offers = arg1;
-
- for (size_t i = 0; i < offers.size(); i++) {
- driver->declineOffer(offers[i].id());
- }
-}
-
-
-// Definition of a mock Executor to be used in tests with gmock.
-class MockExecutor : public Executor
-{
-public:
- MOCK_METHOD4(registered, void(ExecutorDriver*,
- const ExecutorInfo&,
- const FrameworkInfo&,
- const SlaveInfo&));
- MOCK_METHOD2(reregistered, void(ExecutorDriver*, const SlaveInfo&));
- MOCK_METHOD1(disconnected, void(ExecutorDriver*));
- MOCK_METHOD2(launchTask, void(ExecutorDriver*, const TaskInfo&));
- MOCK_METHOD2(killTask, void(ExecutorDriver*, const TaskID&));
- MOCK_METHOD2(frameworkMessage, void(ExecutorDriver*, const std::string&));
- MOCK_METHOD1(shutdown, void(ExecutorDriver*));
- MOCK_METHOD2(error, void(ExecutorDriver*, const std::string&));
-};
-
-
-class MockProcessListener : public slave::ProcessExitedListener
-{
-public:
- MOCK_METHOD2(processExited, void(pid_t, int));
-};
-
-
-template <typename T = master::AllocatorProcess>
-class MockAllocatorProcess : public master::AllocatorProcess
-{
-public:
- MockAllocatorProcess()
- {
- // Spawn the underlying allocator process.
- process::spawn(real);
-
- using ::testing::_;
-
- ON_CALL(*this, initialize(_, _))
- .WillByDefault(InvokeInitialize(this));
-
- ON_CALL(*this, frameworkAdded(_, _, _))
- .WillByDefault(InvokeFrameworkAdded(this));
-
- ON_CALL(*this, frameworkRemoved(_))
- .WillByDefault(InvokeFrameworkRemoved(this));
-
- ON_CALL(*this, frameworkActivated(_, _))
- .WillByDefault(InvokeFrameworkActivated(this));
-
- ON_CALL(*this, frameworkDeactivated(_))
- .WillByDefault(InvokeFrameworkDeactivated(this));
-
- ON_CALL(*this, slaveAdded(_, _, _))
- .WillByDefault(InvokeSlaveAdded(this));
-
- ON_CALL(*this, slaveRemoved(_))
- .WillByDefault(InvokeSlaveRemoved(this));
-
- ON_CALL(*this, updateWhitelist(_))
- .WillByDefault(InvokeUpdateWhitelist(this));
-
- ON_CALL(*this, resourcesRequested(_, _))
- .WillByDefault(InvokeResourcesRequested(this));
-
- ON_CALL(*this, resourcesUnused(_, _, _, _))
- .WillByDefault(InvokeResourcesUnused(this));
-
- ON_CALL(*this, resourcesRecovered(_, _, _))
- .WillByDefault(InvokeResourcesRecovered(this));
-
- ON_CALL(*this, offersRevived(_))
- .WillByDefault(InvokeOffersRevived(this));
- }
-
- ~MockAllocatorProcess()
- {
- process::terminate(real);
- process::wait(real);
- }
-
- MOCK_METHOD2(initialize, void(const master::Flags&,
- const process::PID<master::Master>&));
- MOCK_METHOD3(frameworkAdded, void(const FrameworkID&,
- const FrameworkInfo&,
- const Resources&));
- MOCK_METHOD1(frameworkRemoved, void(const FrameworkID&));
- MOCK_METHOD2(frameworkActivated, void(const FrameworkID&,
- const FrameworkInfo&));
- MOCK_METHOD1(frameworkDeactivated, void(const FrameworkID&));
- MOCK_METHOD3(slaveAdded, void(const SlaveID&,
- const SlaveInfo&,
- const hashmap<FrameworkID, Resources>&));
- MOCK_METHOD1(slaveRemoved, void(const SlaveID&));
- MOCK_METHOD1(updateWhitelist, void(const Option<hashset<std::string> >&));
- MOCK_METHOD2(resourcesRequested, void(const FrameworkID&,
- const std::vector<Request>&));
- MOCK_METHOD4(resourcesUnused, void(const FrameworkID&,
- const SlaveID&,
- const Resources&,
- const Option<Filters>& filters));
- MOCK_METHOD3(resourcesRecovered, void(const FrameworkID&,
- const SlaveID&,
- const Resources&));
- MOCK_METHOD1(offersRevived, void(const FrameworkID&));
-
- T real;
-};
-
-
-typedef ::testing::Types<master::HierarchicalDRFAllocatorProcess>
-AllocatorTypes;
-
-
-// The following actions make up for the fact that DoDefault
-// cannot be used inside a DoAll, for example:
-// EXPECT_CALL(allocator, frameworkAdded(_, _, _))
-// .WillOnce(DoAll(InvokeFrameworkAdded(&allocator),
-// FutureSatisfy(&frameworkAdded)));
-
-ACTION_P(InvokeInitialize, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::initialize,
- arg0,
- arg1);
-}
-
-
-ACTION_P(InvokeFrameworkAdded, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkAdded,
- arg0,
- arg1,
- arg2);
-}
-
-
-ACTION_P(InvokeFrameworkRemoved, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkRemoved, arg0);
-}
-
-
-ACTION_P(InvokeFrameworkActivated, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkActivated,
- arg0,
- arg1);
-}
-
-
-ACTION_P(InvokeFrameworkDeactivated, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkDeactivated,
- arg0);
-}
-
-
-ACTION_P(InvokeSlaveAdded, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::slaveAdded,
- arg0,
- arg1,
- arg2);
-}
-
-
-ACTION_P(InvokeSlaveRemoved, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::slaveRemoved,
- arg0);
-}
-
-
-ACTION_P(InvokeUpdateWhitelist, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::updateWhitelist,
- arg0);
-}
-
-
-ACTION_P(InvokeResourcesRequested, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesRequested,
- arg0,
- arg1);
-}
-
-
-
-ACTION_P(InvokeResourcesUnused, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesUnused,
- arg0,
- arg1,
- arg2,
- arg3);
-}
-
-
-ACTION_P2(InvokeUnusedWithFilters, allocator, timeout)
-{
- Filters filters;
- filters.set_refuse_seconds(timeout);
-
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesUnused,
- arg0,
- arg1,
- arg2,
- filters);
-}
-
-
-ACTION_P(InvokeResourcesRecovered, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesRecovered,
- arg0,
- arg1,
- arg2);
-}
-
-
-ACTION_P(InvokeOffersRevived, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::offersRevived,
- arg0);
-}
-
-
-class OfferEqMatcher
- : public ::testing::MatcherInterface<const std::vector<Offer>& >
-{
-public:
- OfferEqMatcher(int _cpus, int _mem)
- : cpus(_cpus), mem(_mem) {}
-
- virtual bool MatchAndExplain(const std::vector<Offer>& offers,
- ::testing::MatchResultListener* listener) const
- {
- double totalCpus = 0;
- double totalMem = 0;
-
- foreach (const Offer& offer, offers) {
- foreach (const Resource& resource, offer.resources()) {
- if (resource.name() == "cpus") {
- totalCpus += resource.scalar().value();
- } else if (resource.name() == "mem") {
- totalMem += resource.scalar().value();
- }
- }
- }
-
- bool matches = totalCpus == cpus && totalMem == mem;
-
- if (!matches) {
- *listener << totalCpus << " cpus and " << totalMem << "mem";
- }
-
- return matches;
- }
-
- virtual void DescribeTo(::std::ostream* os) const
- {
- *os << "contains " << cpus << " cpus and " << mem << " mem";
- }
-
- virtual void DescribeNegationTo(::std::ostream* os) const
- {
- *os << "does not contain " << cpus << " cpus and " << mem << " mem";
- }
-
-private:
- int cpus;
- int mem;
-};
-
-
-inline const ::testing::Matcher<const std::vector<Offer>& > OfferEq(int cpus, int mem)
-{
- return MakeMatcher(new OfferEqMatcher(cpus, mem));
-}
-
-
-// Definition of the SendStatusUpdateFromTask action to be used with gmock.
-ACTION_P(SendStatusUpdateFromTask, state)
-{
- TaskStatus status;
- status.mutable_task_id()->MergeFrom(arg1.task_id());
- status.set_state(state);
- arg0->sendStatusUpdate(status);
-}
-
-
-// Definition of the SendStatusUpdateFromTaskID action to be used with gmock.
-ACTION_P(SendStatusUpdateFromTaskID, state)
-{
- TaskStatus status;
- status.mutable_task_id()->MergeFrom(arg1);
- status.set_state(state);
- arg0->sendStatusUpdate(status);
-}
-
-
-#define FUTURE_PROTOBUF(message, from, to) \
- FutureProtobuf(message, from, to)
-
-
-#define DROP_PROTOBUF(message, from, to) \
- FutureProtobuf(message, from, to, true)
-
-
-#define DROP_PROTOBUFS(message, from, to) \
- DropProtobufs(message, from, to)
-
-
-// Forward declaration.
-template <typename T>
-T _FutureProtobuf(const process::Message& message);
-
-
-template <typename T, typename From, typename To>
-process::Future<T> FutureProtobuf(T t, From from, To to, bool drop = false)
-{
- // Help debugging by adding some "type constraints".
- { google::protobuf::Message* m = &t; (void) m; }
-
- return process::FutureMessage(testing::Eq(t.GetTypeName()), from, to, drop)
- .then(lambda::bind(&_FutureProtobuf<T>, lambda::_1));
-}
-
-
-template <typename T>
-T _FutureProtobuf(const process::Message& message)
-{
- T t;
- t.ParseFromString(message.body);
- return t;
-}
-
-
-template <typename T, typename From, typename To>
-void DropProtobufs(T t, From from, To to)
-{
- // Help debugging by adding some "type constraints".
- { google::protobuf::Message* m = &t; (void) m; }
-
- process::DropMessages(testing::Eq(t.GetTypeName()), from, to);
-}
-
} // namespace tests {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.cpp b/src/tests/zookeeper.cpp
index 3d11209..237d54c 100644
--- a/src/tests/zookeeper.cpp
+++ b/src/tests/zookeeper.cpp
@@ -35,7 +35,7 @@
#include "logging/logging.hpp"
-#include "tests/utils.hpp"
+#include "tests/flags.hpp"
#include "tests/zookeeper.hpp"
#include "tests/zookeeper_test_server.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/zookeeper.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.hpp b/src/tests/zookeeper.hpp
index 17e0886..1bc38c2 100644
--- a/src/tests/zookeeper.hpp
+++ b/src/tests/zookeeper.hpp
@@ -29,7 +29,6 @@
#include <stout/duration.hpp>
-#include "tests/utils.hpp"
#include "tests/zookeeper_test_server.hpp"
namespace mesos {
@@ -72,7 +71,7 @@ inline ::testing::AssertionResult AssertZKGet(
// the variable 'server'. This test fixture ensures the server is
// started before each test and shutdown after it so that each test is
// presented with a ZooKeeper ensemble with no data or watches.
-class ZooKeeperTest : public MesosTest
+class ZooKeeperTest : public ::testing::Test
{
public:
// A watcher that is useful to install in a ZooKeeper client for
@@ -116,17 +115,18 @@ public:
pthread_cond_t cond;
};
- ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
- virtual ~ZooKeeperTest() { delete server; }
-
static void SetUpTestCase();
protected:
+ ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
+ virtual ~ZooKeeperTest() { delete server; }
+
virtual void SetUp();
// A very long session timeout that simulates no timeout for test cases.
static const Duration NO_TIMEOUT;
+ // TODO(benh): Share the same ZooKeeperTestServer across all tests?
ZooKeeperTestServer* server;
};
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_tests.cpp b/src/tests/zookeeper_tests.cpp
index 27a6048..77a5ab2 100644
--- a/src/tests/zookeeper_tests.cpp
+++ b/src/tests/zookeeper_tests.cpp
@@ -24,7 +24,8 @@
#include <stout/strings.hpp>
-#include "tests/utils.hpp"
+#include "zookeeper/authentication.hpp"
+
#include "tests/zookeeper.hpp"
using namespace mesos::internal;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/zookeeper/authentication.hpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/authentication.hpp b/src/zookeeper/authentication.hpp
index fb0e3ca..7b6b767 100644
--- a/src/zookeeper/authentication.hpp
+++ b/src/zookeeper/authentication.hpp
@@ -5,6 +5,8 @@
#include <string>
+#include "logging/logging.hpp"
+
namespace zookeeper {
struct Authentication
@@ -13,7 +15,11 @@ struct Authentication
const std::string& _scheme,
const std::string& _credentials)
: scheme(_scheme),
- credentials(_credentials) {}
+ credentials(_credentials)
+ {
+ // TODO(benh): Fix output operator below once this changes.
+ CHECK_EQ(scheme, "digest") << "Unsupported authentication scheme";
+ }
const std::string scheme;
const std::string credentials;
@@ -28,6 +34,17 @@ extern const ACL_vector EVERYONE_READ_CREATOR_ALL;
// we're the the only authenticated user to mutate our nodes.
extern const ACL_vector EVERYONE_CREATE_AND_READ_CREATOR_ALL;
+
+inline std::ostream& operator << (
+ std::ostream& stream,
+ const Authentication& authentication)
+{
+ // TODO(benh): Fix this once we support more than just 'digest'.
+ CHECK_EQ(authentication.scheme, "digest");
+ return stream << authentication.credentials;
+}
+
+
} // namespace zookeeper {
#endif // __ZOOKEEPER_AUTHENTICATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/zookeeper/url.hpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/url.hpp b/src/zookeeper/url.hpp
index b297a16..11f2bdd 100644
--- a/src/zookeeper/url.hpp
+++ b/src/zookeeper/url.hpp
@@ -108,6 +108,15 @@ inline Try<URL> URL::parse(const std::string& url)
}
}
+inline std::ostream& operator << (std::ostream& stream, const URL& url)
+{
+ stream << "zk://";
+ if (url.authentication.isSome()) {
+ stream << url.authentication.get() << "@";
+ }
+ return stream << url.servers << url.path;
+}
+
} // namespace zookeeper {
#endif // __ZOOKEEPER_URL_HPP__