You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2015/04/09 21:27:44 UTC
[2/2] mesos git commit: Improved testing around state.json endpoints.
Improved testing around state.json endpoints.
Review: https://reviews.apache.org/r/32463
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/99cd79ce
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/99cd79ce
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/99cd79ce
Branch: refs/heads/master
Commit: 99cd79ce5d3014ce8e6ed258322f5b922c62e07b
Parents: a5a2833
Author: Benjamin Mahler <be...@gmail.com>
Authored: Tue Mar 24 16:08:09 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Thu Apr 9 12:26:36 2015 -0700
----------------------------------------------------------------------
src/tests/master_tests.cpp | 126 ++++++++++++++++++++++++++++++++--------
src/tests/slave_tests.cpp | 78 ++++++++++++++++++++-----
2 files changed, 166 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/99cd79ce/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 2bfd0f8..32b1e9b 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -30,7 +30,6 @@
#include <process/future.hpp>
#include <process/gmock.hpp>
#include <process/http.hpp>
-#include <process/owned.hpp>
#include <process/pid.hpp>
#include <process/metrics/counter.hpp>
@@ -44,6 +43,8 @@
#include <stout/strings.hpp>
#include <stout/try.hpp>
+#include "common/build.hpp"
+
#include "master/flags.hpp"
#include "master/master.hpp"
@@ -74,10 +75,8 @@ using mesos::internal::slave::MesosContainerizerProcess;
using process::Clock;
using process::Future;
-using process::Owned;
using process::PID;
using process::Promise;
-using process::UPID;
using std::string;
using std::vector;
@@ -94,6 +93,8 @@ namespace mesos {
namespace internal {
namespace tests {
+namespace http = process::http;
+
// Those of the overall Mesos master/slave/scheduler/driver tests
// that seem vaguely more master than slave-related are in this file.
// The others are in "slave_tests.cpp".
@@ -271,8 +272,7 @@ TEST_F(MasterTest, ShutdownFrameworkWhileTaskRunning)
Clock::resume();
// Request master state.
- Future<process::http::Response> response =
- process::http::get(master.get(), "state.json");
+ Future<http::Response> response = http::get(master.get(), "state.json");
AWAIT_READY(response);
// These checks are not essential for the test, but may help
@@ -1596,8 +1596,7 @@ TEST_F(MasterTest, SlavesEndpointWithoutSlaves)
ASSERT_SOME(master);
// Query the master.
- const Future<process::http::Response> response =
- process::http::get(master.get(), "slaves");
+ Future<http::Response> response = http::get(master.get(), "slaves");
AWAIT_READY(response);
@@ -1645,8 +1644,7 @@ TEST_F(MasterTest, SlavesEndpointTwoSlaves)
AWAIT_READY(slave2RegisteredMessage);
// Query the master.
- const Future<process::http::Response> response =
- process::http::get(master.get(), "slaves");
+ Future<http::Response> response = http::get(master.get(), "slaves");
AWAIT_READY(response);
@@ -2192,8 +2190,7 @@ TEST_F(MasterTest, OrphanTasks)
EXPECT_EQ(TASK_RUNNING, status.get().state());
// Get the master's state.
- Future<process::http::Response> response =
- process::http::get(master.get(), "state.json");
+ Future<http::Response> response = http::get(master.get(), "state.json");
AWAIT_READY(response);
EXPECT_SOME_EQ(
@@ -2258,7 +2255,7 @@ TEST_F(MasterTest, OrphanTasks)
AWAIT_READY(reregisterFrameworkMessage);
// Get the master's state.
- response = process::http::get(master.get(), "state.json");
+ response = http::get(master.get(), "state.json");
AWAIT_READY(response);
EXPECT_SOME_EQ(
@@ -2290,7 +2287,7 @@ TEST_F(MasterTest, OrphanTasks)
AWAIT_READY(frameworkRegisteredMessage);
// Get the master's state.
- response = process::http::get(master.get(), "state.json");
+ response = http::get(master.get(), "state.json");
AWAIT_READY(response);
EXPECT_SOME_EQ(
@@ -2743,6 +2740,93 @@ TEST_F(MasterTest, ReleaseResourcesForTerminalTaskWithPendingUpdates)
}
+TEST_F(MasterTest, StateEndpoint)
+{
+ master::Flags flags = CreateMasterFlags();
+
+ flags.hostname = "localhost";
+ flags.cluster = "test-cluster";
+
+ // Capture the start time deterministically.
+ Clock::pause();
+
+ Try<PID<Master>> master = StartMaster(flags);
+ ASSERT_SOME(master);
+
+ Future<http::Response> response = http::get(master.get(), "state.json");
+
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(http::OK().status, response);
+
+ EXPECT_SOME_EQ(
+ "application/json",
+ response.get().headers.get("Content-Type"));
+
+ Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.get().body);
+ ASSERT_SOME(parse);
+
+ JSON::Object state = parse.get();
+
+ EXPECT_EQ(MESOS_VERSION, state.values["version"]);
+
+ if (build::GIT_SHA.isSome()) {
+ EXPECT_EQ(build::GIT_SHA.get(), state.values["git_sha"]);
+ }
+
+ if (build::GIT_BRANCH.isSome()) {
+ EXPECT_EQ(build::GIT_BRANCH.get(), state.values["git_branch"]);
+ }
+
+ if (build::GIT_TAG.isSome()) {
+ EXPECT_EQ(build::GIT_TAG.get(), state.values["git_tag"]);
+ }
+
+ EXPECT_EQ(build::DATE, state.values["build_date"]);
+ EXPECT_EQ(build::TIME, state.values["build_time"]);
+ EXPECT_EQ(build::USER, state.values["build_user"]);
+
+ ASSERT_TRUE(state.values["start_time"].is<JSON::Number>());
+ EXPECT_EQ(
+ static_cast<int>(Clock::now().secs()),
+ static_cast<int>(state.values["start_time"].as<JSON::Number>().value));
+
+ ASSERT_TRUE(state.values["id"].is<JSON::String>());
+ EXPECT_NE("", state.values["id"].as<JSON::String>().value);
+
+ EXPECT_EQ(stringify(master.get()), state.values["pid"]);
+ EXPECT_EQ(flags.hostname.get(), state.values["hostname"]);
+
+ EXPECT_EQ(0, state.values["activated_slaves"]);
+ EXPECT_EQ(0, state.values["deactivated_slaves"]);
+
+ EXPECT_EQ(flags.cluster.get(), state.values["cluster"]);
+
+ // TODO(bmahler): Test "leader", "log_dir", "external_log_file".
+
+ // TODO(bmahler): Ensure this contains all the flags.
+ ASSERT_TRUE(state.values["flags"].is<JSON::Object>());
+ EXPECT_FALSE(state.values["flags"].as<JSON::Object>().values.empty());
+
+ ASSERT_TRUE(state.values["slaves"].is<JSON::Array>());
+ EXPECT_TRUE(state.values["slaves"].as<JSON::Array>().values.empty());
+
+ ASSERT_TRUE(state.values["orphan_tasks"].is<JSON::Array>());
+ EXPECT_TRUE(state.values["orphan_tasks"].as<JSON::Array>().values.empty());
+
+ ASSERT_TRUE(state.values["frameworks"].is<JSON::Array>());
+ EXPECT_TRUE(state.values["frameworks"].as<JSON::Array>().values.empty());
+
+ ASSERT_TRUE(
+ state.values["completed_frameworks"].is<JSON::Array>());
+ EXPECT_TRUE(
+ state.values["completed_frameworks"].as<JSON::Array>().values.empty());
+
+ ASSERT_TRUE(
+ state.values["unregistered_frameworks"].is<JSON::Array>());
+ EXPECT_TRUE(
+ state.values["unregistered_frameworks"].as<JSON::Array>().values.empty());
+}
+
+
// This test ensures that the web UI of a framework is included in the
// state.json endpoint, if provided by the framework.
TEST_F(MasterTest, FrameworkWebUIUrl)
@@ -2765,9 +2849,8 @@ TEST_F(MasterTest, FrameworkWebUIUrl)
AWAIT_READY(registered);
- Future<process::http::Response> masterState =
- process::http::get(master.get(), "state.json");
- AWAIT_EXPECT_RESPONSE_STATUS_EQ(process::http::OK().status, masterState);
+ Future<http::Response> masterState = http::get(master.get(), "state.json");
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(http::OK().status, masterState);
Try<JSON::Object> masterStateObject =
JSON::parse<JSON::Object>(masterState.get().body);
@@ -2876,8 +2959,7 @@ TEST_F(MasterTest, TaskLabels)
AWAIT_READY(update);
// Verify label key and value in master state.json.
- Future<process::http::Response> response =
- process::http::get(master.get(), "state.json");
+ Future<http::Response> response = http::get(master.get(), "state.json");
AWAIT_READY(response);
EXPECT_SOME_EQ(
@@ -2954,8 +3036,7 @@ TEST_F(MasterTest, SlaveActiveEndpoint)
AWAIT_READY(slaveRegisteredMessage);
// Verify slave is active.
- Future<process::http::Response> response =
- process::http::get(master.get(), "state.json");
+ Future<http::Response> response = http::get(master.get(), "state.json");
AWAIT_READY(response);
Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.get().body);
@@ -2977,7 +3058,7 @@ TEST_F(MasterTest, SlaveActiveEndpoint)
AWAIT_READY(deactivateSlave);
// Verify slave is inactive.
- response = process::http::get(master.get(), "state.json");
+ response = http::get(master.get(), "state.json");
AWAIT_READY(response);
parse = JSON::parse<JSON::Object>(response.get().body);
@@ -3082,8 +3163,7 @@ TEST_F(MasterTest, TaskDiscoveryInfo)
AWAIT_READY(update);
// Verify label key and value in master state.json.
- Future<process::http::Response> response =
- process::http::get(master.get(), "state.json");
+ Future<http::Response> response = http::get(master.get(), "state.json");
AWAIT_READY(response);
EXPECT_SOME_EQ(
http://git-wip-us.apache.org/repos/asf/mesos/blob/99cd79ce/src/tests/slave_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp
index fd09d65..29d23c6 100644
--- a/src/tests/slave_tests.cpp
+++ b/src/tests/slave_tests.cpp
@@ -31,8 +31,6 @@
#include <process/clock.hpp>
#include <process/future.hpp>
#include <process/gmock.hpp>
-#include <process/io.hpp>
-#include <process/owned.hpp>
#include <process/pid.hpp>
#include <process/subprocess.hpp>
@@ -41,6 +39,7 @@
#include <stout/os.hpp>
#include <stout/try.hpp>
+#include "common/build.hpp"
#include "common/http.hpp"
#include "master/flags.hpp"
@@ -64,10 +63,14 @@ using memory::shared_ptr;
using namespace mesos::internal::slave;
-using namespace process;
-
using mesos::internal::master::Master;
+using process::Clock;
+using process::Future;
+using process::PID;
+using process::Promise;
+using process::UPID;
+
using std::map;
using std::string;
using std::vector;
@@ -86,6 +89,8 @@ namespace mesos {
namespace internal {
namespace tests {
+namespace http = process::http;
+
// Those of the overall Mesos master/slave/scheduler/driver tests
// that seem vaguely more slave than master-related are in this file.
// The others are in "master_tests.cpp".
@@ -887,16 +892,19 @@ TEST_F(SlaveTest, StateEndpoint)
slave::Flags flags = this->CreateSlaveFlags();
+ flags.hostname = "localhost";
flags.resources = "cpus:4;mem:2048;disk:512;ports:[33000-34000]";
flags.attributes = "rack:abc;host:myhost";
+ // Capture the start time deterministically.
+ Clock::pause();
+
Try<PID<Slave> > slave = StartSlave(flags);
ASSERT_SOME(slave);
- Future<http::Response> response =
- http::get(slave.get(), "state.json");
+ Future<http::Response> response = http::get(slave.get(), "state.json");
- AWAIT_READY(response);
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(http::OK().status, response);
EXPECT_SOME_EQ(
"application/json",
@@ -908,20 +916,61 @@ TEST_F(SlaveTest, StateEndpoint)
JSON::Object state = parse.get();
- // Check if 'resources' matches.
+ EXPECT_EQ(MESOS_VERSION, state.values["version"]);
+
+ if (build::GIT_SHA.isSome()) {
+ EXPECT_EQ(build::GIT_SHA.get(), state.values["git_sha"]);
+ }
+
+ if (build::GIT_BRANCH.isSome()) {
+ EXPECT_EQ(build::GIT_BRANCH.get(), state.values["git_branch"]);
+ }
+
+ if (build::GIT_TAG.isSome()) {
+ EXPECT_EQ(build::GIT_TAG.get(), state.values["git_tag"]);
+ }
+
+ EXPECT_EQ(build::DATE, state.values["build_date"]);
+ EXPECT_EQ(build::TIME, state.values["build_time"]);
+ EXPECT_EQ(build::USER, state.values["build_user"]);
+
+ ASSERT_TRUE(state.values["start_time"].is<JSON::Number>());
+ EXPECT_EQ(
+ static_cast<int>(Clock::now().secs()),
+ static_cast<int>(state.values["start_time"].as<JSON::Number>().value));
+
+ // TODO(bmahler): The slave must register for the 'id'
+ // to be non-empty.
+ ASSERT_TRUE(state.values["id"].is<JSON::String>());
+
+ EXPECT_EQ(stringify(slave.get()), state.values["pid"]);
+ EXPECT_EQ(flags.hostname.get(), state.values["hostname"]);
+
Try<Resources> resources = Resources::parse(
flags.resources.get(), flags.default_role);
ASSERT_SOME(resources);
- ASSERT_EQ(1u, state.values.count("resources"));
- EXPECT_EQ(state.values["resources"], JSON::Value(model(resources.get())));
+ EXPECT_EQ(model(resources.get()), state.values["resources"]);
- // Check if 'attributes' matches.
Attributes attributes = Attributes::parse(flags.attributes.get());
- ASSERT_EQ(1u, state.values.count("attributes"));
- EXPECT_EQ(state.values["attributes"], JSON::Value(model(attributes)));
+ EXPECT_EQ(model(attributes), state.values["attributes"]);
+
+ // TODO(bmahler): Test "master_hostname", "log_dir",
+ // "external_log_file".
+
+ ASSERT_TRUE(state.values["frameworks"].is<JSON::Array>());
+ EXPECT_TRUE(state.values["frameworks"].as<JSON::Array>().values.empty());
+
+ ASSERT_TRUE(
+ state.values["completed_frameworks"].is<JSON::Array>());
+ EXPECT_TRUE(
+ state.values["completed_frameworks"].as<JSON::Array>().values.empty());
+
+ // TODO(bmahler): Ensure this contains all the flags.
+ ASSERT_TRUE(state.values["flags"].is<JSON::Object>());
+ EXPECT_FALSE(state.values["flags"].as<JSON::Object>().values.empty());
Shutdown();
}
@@ -1749,8 +1798,7 @@ TEST_F(SlaveTest, TaskLabels)
AWAIT_READY(update);
// Verify label key and value in slave state.json.
- Future<http::Response> response =
- http::get(slave.get(), "state.json");
+ Future<http::Response> response = http::get(slave.get(), "state.json");
AWAIT_READY(response);
EXPECT_SOME_EQ(