You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2016/06/18 02:51:31 UTC

[1/5] mesos git commit: Extracted task collection logic to helper function.

Repository: mesos
Updated Branches:
  refs/heads/master a6f1587f7 -> ec41d1aa8


Extracted task collection logic to helper function.

Added a helper function _tasks() to collect tasks. This is
to be used by both tasks() and getTasks() in operator API.

Review: https://reviews.apache.org/r/48400/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/608e3823
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/608e3823
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/608e3823

Branch: refs/heads/master
Commit: 608e3823dbc19fabf70687840f27b1a628ac0cd6
Parents: a6f1587
Author: Jay Guo <gu...@cn.ibm.com>
Authored: Fri Jun 17 19:50:35 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Jun 17 19:50:35 2016 -0700

----------------------------------------------------------------------
 src/master/http.cpp   | 75 +++++++++++++++++++++++++++++-----------------
 src/master/master.hpp |  6 ++++
 2 files changed, 53 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/608e3823/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index dca814b..2d326ef 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -2692,6 +2692,40 @@ Future<Response> Master::Http::tasks(
     return redirect(request);
   }
 
+  // Get list options (limit and offset).
+  Result<int> result = numify<int>(request.url.query.get("limit"));
+  size_t limit = result.isSome() ? result.get() : TASK_LIMIT;
+
+  result = numify<int>(request.url.query.get("offset"));
+  size_t offset = result.isSome() ? result.get() : 0;
+
+  Option<string> order = request.url.query.get("order");
+  string _order = order.isSome() && (order.get() == "asc") ? "asc" : "des";
+
+  return _tasks(limit, offset, _order, principal)
+    .then([=](const vector<const Task*>& tasks) -> Response {
+      auto tasksWriter = [&tasks](JSON::ObjectWriter* writer) {
+        writer->field("tasks", [&tasks](JSON::ArrayWriter* writer) {
+          foreach (const Task* task, tasks) {
+            writer->element(*task);
+          }
+        });
+      };
+
+      return OK(jsonify(tasksWriter), request.url.query.get("jsonp"));
+    })
+    .repair([](const Future<Response>& response) {
+      LOG(WARNING) << "Authorization failed: " << response.failure();
+      return InternalServerError(response.failure());
+    });
+}
+
+Future<vector<const Task*>> Master::Http::_tasks(
+    const size_t limit,
+    const size_t offset,
+    const string& order,
+    const Option<string>& principal) const
+{
   // Retrieve Approvers for authorizing frameworks and tasks.
   Future<Owned<ObjectApprover>> frameworksApprover;
   Future<Owned<ObjectApprover>> tasksApprover;
@@ -2717,23 +2751,16 @@ Future<Response> Master::Http::tasks(
   }
 
   return collect(frameworksApprover, tasksApprover, executorsApprover)
-    .then(defer(master->self(),
-        [=](const tuple<Owned<ObjectApprover>,
-                        Owned<ObjectApprover>,
-                        Owned<ObjectApprover>>& approvers) -> Response {
+    .then([=](const tuple<Owned<ObjectApprover>,
+                          Owned<ObjectApprover>,
+                          Owned<ObjectApprover>>& approvers)
+      -> vector<const Task*> {
       // Get approver from tuple.
       Owned<ObjectApprover> frameworksApprover;
       Owned<ObjectApprover> tasksApprover;
       Owned<ObjectApprover> executorsApprover;
       tie(frameworksApprover, tasksApprover, executorsApprover) = approvers;
 
-      // Get list options (limit and offset).
-      Result<int> result = numify<int>(request.url.query.get("limit"));
-      size_t limit = result.isSome() ? result.get() : TASK_LIMIT;
-
-      result = numify<int>(request.url.query.get("offset"));
-      size_t offset = result.isSome() ? result.get() : 0;
-
       // TODO(nnielsen): Currently, formatting errors in offset and/or limit
       // will silently be ignored. This could be reported to the user instead.
 
@@ -2782,29 +2809,21 @@ Future<Response> Master::Http::tasks(
       // Sort tasks by task status timestamp. Default order is descending.
       // The earliest timestamp is chosen for comparison when
       // multiple are present.
-      Option<string> order = request.url.query.get("order");
-      if (order.isSome() && (order.get() == "asc")) {
+      if (order == "asc") {
         sort(tasks.begin(), tasks.end(), TaskComparator::ascending);
       } else {
         sort(tasks.begin(), tasks.end(), TaskComparator::descending);
       }
 
-      auto tasksWriter = [&tasks, limit, offset](JSON::ObjectWriter* writer) {
-        writer->field("tasks",
-                      [&tasks, limit, offset](JSON::ArrayWriter* writer) {
-          size_t end = std::min(offset + limit, tasks.size());
-          for (size_t i = offset; i < end; i++) {
-            const Task* task = tasks[i];
-            writer->element(*task);
-          }
-        });
-      };
+      // Collect 'limit' number of tasks starting from 'offset'.
+      vector<const Task*> _tasks;
+      size_t end = std::min(offset + limit, tasks.size());
+      for (size_t i = offset; i < end; i++) {
+        const Task* task = tasks[i];
+        _tasks.push_back(task);
+      }
 
-      return OK(jsonify(tasksWriter), request.url.query.get("jsonp"));
-  }))
-  .repair([](const Future<Response>& response) {
-    LOG(WARNING) << "Authorization failed: " << response.failure();
-    return InternalServerError(response.failure());
+      return _tasks;
   });
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/608e3823/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 2bddfe1..ea846f9 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1237,6 +1237,12 @@ private:
   private:
     JSON::Object _flags() const;
 
+    process::Future<std::vector<const Task*>> _tasks(
+        const size_t limit,
+        const size_t offset,
+        const std::string& order,
+        const Option<std::string>& principal) const;
+
     process::Future<process::http::Response> _teardown(
         const FrameworkID& id) const;
 


[3/5] mesos git commit: Added Task proto message to v1/mesos.proto.

Posted by vi...@apache.org.
Added Task proto message to v1/mesos.proto.

Review: https://reviews.apache.org/r/48449/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/26fed989
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/26fed989
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/26fed989

Branch: refs/heads/master
Commit: 26fed9898db8594a1a966c6e05164d310d2194e0
Parents: 51ef622
Author: Jay Guo <gu...@cn.ibm.com>
Authored: Fri Jun 17 19:50:56 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Jun 17 19:50:56 2016 -0700

----------------------------------------------------------------------
 include/mesos/v1/mesos.proto | 49 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/26fed989/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index dca0c2c..1da6f92 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1300,6 +1300,55 @@ message TaskInfo {
 }
 
 
+// TODO(bmahler): Add executor_uuid here, and send it to the master. This will
+// allow us to expose executor work directories for tasks in the webui when
+// looking from the master level. Currently only the agent knows which run the
+// task belongs to.
+/**
+ * Describes a task, similar to `TaskInfo`.
+ *
+ * `Task` is used in some of the Mesos messages found below.
+ * `Task` is used instead of `TaskInfo` if:
+ *   1) we need additional IDs, such as a specific
+ *      framework, executor, or agent; or
+ *   2) we do not need the additional data, such as the command run by the
+ *      task or the health checks.  These additional fields may be large and
+ *      unnecessary for some Mesos messages.
+ *
+ * `Task` is generally constructed from a `TaskInfo`.  See protobuf::createTask.
+ */
+message Task {
+  required string name = 1;
+  required TaskID task_id = 2;
+  required FrameworkID framework_id = 3;
+  optional ExecutorID executor_id = 4;
+  required AgentID agent_id = 5;
+  required TaskState state = 6; // Latest state of the task.
+  repeated Resource resources = 7;
+  repeated TaskStatus statuses = 8;
+
+  // These fields correspond to the state and uuid of the latest
+  // status update forwarded to the master.
+  // NOTE: Either both the fields must be set or both must be unset.
+  optional TaskState status_update_state = 9;
+  optional bytes status_update_uuid = 10;
+
+  optional Labels labels = 11;
+
+  // Service discovery information for the task. It is not interpreted
+  // or acted upon by Mesos. It is up to a service discovery system
+  // to use this information as needed and to handle tasks without
+  // service discovery information.
+  optional DiscoveryInfo discovery = 12;
+
+  // Container information for the task.
+  optional ContainerInfo container = 13;
+
+  // Specific user under which task is running.
+  optional string user = 14;
+}
+
+
 /**
  * Describes possible task states. IMPORTANT: Mesos assumes tasks that
  * enter terminal states (see below) imply the task is no longer


[4/5] mesos git commit: Implemented v1::master::Call::GET_TASKS.

Posted by vi...@apache.org.
Implemented v1::master::Call::GET_TASKS.

Review: https://reviews.apache.org/r/48046/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/7f340fba
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/7f340fba
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/7f340fba

Branch: refs/heads/master
Commit: 7f340fba9f3fda10b8c54ccf49049efc60886051
Parents: 26fed98
Author: Jay Guo <gu...@cn.ibm.com>
Authored: Fri Jun 17 19:51:03 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Jun 17 19:51:03 2016 -0700

----------------------------------------------------------------------
 include/mesos/v1/master/master.proto |   4 --
 src/internal/evolve.cpp              |   6 ++
 src/internal/evolve.hpp              |   1 +
 src/master/http.cpp                  |  41 +++++++++++-
 src/master/master.hpp                |   5 ++
 src/tests/api_tests.cpp              | 104 ++++++++++++++++++++++++++++++
 6 files changed, 156 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/7f340fba/include/mesos/v1/master/master.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/master/master.proto b/include/mesos/v1/master/master.proto
index b45d6d9..59e978f 100644
--- a/include/mesos/v1/master/master.proto
+++ b/include/mesos/v1/master/master.proto
@@ -280,10 +280,6 @@ message Response {
   }
 
   message GetTasks {
-    message Task {
-      // TODO(vinod): Fill in the fields.
-    }
-
     repeated Task tasks = 1;
   }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/7f340fba/src/internal/evolve.cpp
----------------------------------------------------------------------
diff --git a/src/internal/evolve.cpp b/src/internal/evolve.cpp
index dc2d2c8..67c5503 100644
--- a/src/internal/evolve.cpp
+++ b/src/internal/evolve.cpp
@@ -150,6 +150,12 @@ v1::TaskStatus evolve(const TaskStatus& status)
 }
 
 
+v1::Task evolve(const Task& task)
+{
+  return evolve<v1::Task>(task);
+}
+
+
 v1::MasterInfo evolve(const MasterInfo& masterInfo)
 {
   return evolve<v1::MasterInfo>(masterInfo);

http://git-wip-us.apache.org/repos/asf/mesos/blob/7f340fba/src/internal/evolve.hpp
----------------------------------------------------------------------
diff --git a/src/internal/evolve.hpp b/src/internal/evolve.hpp
index 875ce89..7ce62d9 100644
--- a/src/internal/evolve.hpp
+++ b/src/internal/evolve.hpp
@@ -65,6 +65,7 @@ v1::OfferID evolve(const OfferID& offerId);
 v1::TaskID evolve(const TaskID& taskId);
 v1::TaskInfo evolve(const TaskInfo& taskInfo);
 v1::TaskStatus evolve(const TaskStatus& status);
+v1::Task evolve(const Task& task);
 v1::MasterInfo evolve(const MasterInfo& masterInfo);
 
 v1::agent::Response evolve(const mesos::agent::Response& response);

http://git-wip-us.apache.org/repos/asf/mesos/blob/7f340fba/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 2d326ef..a6beb17 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -635,7 +635,7 @@ Future<Response> Master::Http::api(
       return NotImplemented();
 
     case mesos::master::Call::GET_TASKS:
-      return NotImplemented();
+      return getTasks(call, principal, acceptType);
 
     case mesos::master::Call::GET_ROLES:
       return NotImplemented();
@@ -1436,6 +1436,45 @@ Future<Response> Master::Http::getLeadingMaster(
 }
 
 
+Future<Response> Master::Http::getTasks(
+    const mesos::master::Call& call,
+    const Option<string>& principal,
+    ContentType contentType) const
+{
+  CHECK_EQ(mesos::master::Call::GET_TASKS, call.type());
+
+  // Get list options (limit and offset).
+  Result<int> result = call.get_tasks().limit();
+  CHECK_SOME(result);
+  size_t limit = result.get();
+
+  result = call.get_tasks().offset();
+  size_t offset = result.isSome() ? result.get() : 0;
+
+  Option<string> order = call.get_tasks().order();
+  string _order = order.isSome() && (order.get() == "asc") ? "asc" : "des";
+
+  return _tasks(limit, offset, _order, principal)
+    .then([contentType](const vector<const Task*>& tasks) -> Response {
+      v1::master::Response response;
+      response.set_type(v1::master::Response::GET_TASKS);
+
+      v1::master::Response::GetTasks* getTasks = response.mutable_get_tasks();
+
+      foreach (const Task* task, tasks) {
+        getTasks->add_tasks()->CopyFrom(evolve(*task));
+      }
+
+      return OK(serialize(contentType, response),
+                stringify(contentType));
+    })
+    .repair([](const Future<Response>& response) {
+      LOG(WARNING) << "Authorization failed: " << response.failure();
+      return InternalServerError(response.failure());
+    });
+}
+
+
 string Master::Http::REDIRECT_HELP()
 {
   return HELP(

http://git-wip-us.apache.org/repos/asf/mesos/blob/7f340fba/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index ea846f9..618d928 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1361,6 +1361,11 @@ private:
         const Option<std::string>& principal,
         ContentType contentType) const;
 
+    process::Future<process::http::Response> getTasks(
+        const mesos::master::Call& call,
+        const Option<std::string>& principal,
+        ContentType contentType) const;
+
     Master* master;
 
     // NOTE: The quota specific pieces of the Operator API are factored

http://git-wip-us.apache.org/repos/asf/mesos/blob/7f340fba/src/tests/api_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/api_tests.cpp b/src/tests/api_tests.cpp
index 41fef2f..afa5ffa 100644
--- a/src/tests/api_tests.cpp
+++ b/src/tests/api_tests.cpp
@@ -38,8 +38,10 @@
 
 #include "slave/slave.hpp"
 
+#include "tests/containerizer.hpp"
 #include "tests/mesos.hpp"
 
+using mesos::master::detector::MasterDetector;
 using mesos::master::detector::StandaloneMasterDetector;
 
 using mesos::internal::slave::Slave;
@@ -226,6 +228,108 @@ TEST_P(MasterAPITest, GetMetrics)
 }
 
 
+// This tests v1 API GetTasks when no task is present.
+TEST_P(MasterAPITest, GetTasksNoRunningTask)
+{
+  Try<Owned<cluster::Master>> master = this->StartMaster();
+  ASSERT_SOME(master);
+
+  v1::master::Call v1Call;
+  v1Call.mutable_get_tasks();
+  v1Call.set_type(v1::master::Call::GET_TASKS);
+
+  ContentType contentType = GetParam();
+
+  Future<v1::master::Response> v1Response =
+    post(master.get()->pid, v1Call, contentType);
+
+  AWAIT_READY(v1Response);
+  ASSERT_TRUE(v1Response.get().IsInitialized());
+  ASSERT_EQ(v1::master::Response::GET_TASKS, v1Response.get().type());
+  ASSERT_EQ(0, v1Response.get().get_tasks().tasks_size());
+}
+
+
+// This tests v1 API GetTasks with 1 running task.
+TEST_P(MasterAPITest, GetTasks)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  MockExecutor exec(DEFAULT_EXECUTOR_ID);
+  TestContainerizer containerizer(&exec);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), &containerizer);
+  ASSERT_SOME(slave);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .Times(1);
+
+  Future<vector<Offer>> offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(offers);
+  EXPECT_NE(0u, offers.get().size());
+
+  TaskInfo task;
+  task.set_name("test");
+  task.mutable_task_id()->set_value("1");
+  task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers.get()[0].resources());
+  task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO);
+
+  EXPECT_CALL(exec, registered(_, _, _, _))
+    .Times(1);
+
+  EXPECT_CALL(exec, launchTask(_, _))
+    .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
+
+  Future<TaskStatus> status;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&status));
+
+  driver.launchTasks(offers.get()[0].id(), {task});
+
+  AWAIT_READY(status);
+  EXPECT_EQ(TASK_RUNNING, status.get().state());
+  EXPECT_TRUE(status.get().has_executor_id());
+  EXPECT_EQ(exec.id, status.get().executor_id());
+
+  v1::master::Call v1Call;
+  v1Call.mutable_get_tasks();
+  v1Call.set_type(v1::master::Call::GET_TASKS);
+
+  ContentType contentType = GetParam();
+
+  Future<v1::master::Response> v1Response =
+    post(master.get()->pid, v1Call, contentType);
+
+  AWAIT_READY(v1Response);
+  ASSERT_TRUE(v1Response.get().IsInitialized());
+  ASSERT_EQ(v1::master::Response::GET_TASKS, v1Response.get().type());
+  ASSERT_EQ(1, v1Response.get().get_tasks().tasks_size());
+  ASSERT_EQ(v1::TaskState::TASK_RUNNING,
+            v1Response.get().get_tasks().tasks(0).state());
+  ASSERT_EQ("test", v1Response.get().get_tasks().tasks(0).name());
+  ASSERT_EQ("1", v1Response.get().get_tasks().tasks(0).task_id().value());
+
+  EXPECT_CALL(exec, shutdown(_))
+    .Times(AtMost(1));
+
+  driver.stop();
+  driver.join();
+}
+
+
 TEST_P(MasterAPITest, GetLoggingLevel)
 {
   Try<Owned<cluster::Master>> master = this->StartMaster();


[5/5] mesos git commit: Added unit test for master /tasks endpoint.

Posted by vi...@apache.org.
Added unit test for master /tasks endpoint.

Review: https://reviews.apache.org/r/48450/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ec41d1aa
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ec41d1aa
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ec41d1aa

Branch: refs/heads/master
Commit: ec41d1aa8321d98000aed95eb7d26a131c41ea95
Parents: 7f340fb
Author: Jay Guo <gu...@cn.ibm.com>
Authored: Fri Jun 17 19:51:13 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Jun 17 19:51:13 2016 -0700

----------------------------------------------------------------------
 src/tests/master_tests.cpp | 89 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/ec41d1aa/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index ad05437..a62d0ab 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -2462,6 +2462,95 @@ TEST_F(MasterTest, OrphanTasks)
 }
 
 
+// This tests /tasks endpoint to return correct task information.
+TEST_F(MasterTest, TasksEndpoint)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  MockExecutor exec(DEFAULT_EXECUTOR_ID);
+  TestContainerizer containerizer(&exec);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), &containerizer);
+  ASSERT_SOME(slave);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .Times(1);
+
+  Future<vector<Offer>> offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(offers);
+  EXPECT_NE(0u, offers.get().size());
+
+  TaskInfo task;
+  task.set_name("test");
+  task.mutable_task_id()->set_value("1");
+  task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers.get()[0].resources());
+  task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO);
+
+  EXPECT_CALL(exec, registered(_, _, _, _))
+    .Times(1);
+
+  EXPECT_CALL(exec, launchTask(_, _))
+    .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
+
+  Future<TaskStatus> status;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&status));
+
+  driver.launchTasks(offers.get()[0].id(), {task});
+
+  AWAIT_READY(status);
+  EXPECT_EQ(TASK_RUNNING, status.get().state());
+  EXPECT_TRUE(status.get().has_executor_id());
+  EXPECT_EQ(exec.id, status.get().executor_id());
+
+  Future<Response> response = process::http::get(
+      master.get()->pid,
+      "tasks",
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+  AWAIT_EXPECT_RESPONSE_HEADER_EQ(APPLICATION_JSON, "Content-Type", response);
+
+  Try<JSON::Value> value = JSON::parse<JSON::Value>(response.get().body);
+  ASSERT_SOME(value);
+
+  Try<JSON::Value> expected = JSON::parse(
+      "{"
+        "\"tasks\":"
+          "[{"
+              "\"executor_id\":\"default\","
+              "\"id\":\"1\","
+              "\"name\":\"test\","
+              "\"state\":\"TASK_RUNNING\""
+          "}]"
+      "}");
+
+  ASSERT_SOME(expected);
+
+  EXPECT_TRUE(value.get().contains(expected.get()));
+
+  EXPECT_CALL(exec, shutdown(_))
+    .Times(AtMost(1));
+
+  driver.stop();
+  driver.join();
+}
+
+
 // This test verifies that the master will strip ephemeral ports
 // resource from offers so that frameworks cannot see it.
 TEST_F(MasterTest, IgnoreEphemeralPortsResource)


[2/5] mesos git commit: Changed GetTask.limit type to int32 with default value 100.

Posted by vi...@apache.org.
Changed GetTask.limit type to int32 with default value 100.

This protobuf message should be int32 instead of string.
Default value is set to TASK_LIMIT (100).

Review: https://reviews.apache.org/r/48401/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/51ef622e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/51ef622e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/51ef622e

Branch: refs/heads/master
Commit: 51ef622e15174310463ae52385d699ab6281eec4
Parents: 608e382
Author: Jay Guo <gu...@cn.ibm.com>
Authored: Fri Jun 17 19:50:49 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Jun 17 19:50:49 2016 -0700

----------------------------------------------------------------------
 include/mesos/master/master.proto    | 6 +++++-
 include/mesos/v1/master/master.proto | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/51ef622e/include/mesos/master/master.proto
----------------------------------------------------------------------
diff --git a/include/mesos/master/master.proto b/include/mesos/master/master.proto
index 3b85b81..fa92240 100644
--- a/include/mesos/master/master.proto
+++ b/include/mesos/master/master.proto
@@ -115,8 +115,12 @@ message Call {
     optional string length = 3;
   }
 
+  // Call::GetTasks requests 'limit' number of tasks starting
+  // from 'offset'. Tasks are sorted in 'order', either ascending
+  // or descending based on timestamp. If 'limit' is not set,
+  // default value 100 will be used.
   message GetTasks {
-    optional string limit = 1;
+    optional uint32 limit = 1 [default = 100];
     optional uint32 offset = 2;
     optional string order = 3;
   }

http://git-wip-us.apache.org/repos/asf/mesos/blob/51ef622e/include/mesos/v1/master/master.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/master/master.proto b/include/mesos/v1/master/master.proto
index 5a6bbeb..b45d6d9 100644
--- a/include/mesos/v1/master/master.proto
+++ b/include/mesos/v1/master/master.proto
@@ -115,8 +115,12 @@ message Call {
     optional string length = 3;
   }
 
+  // Call::GetTasks requests 'limit' number of tasks starting
+  // from 'offset'. Tasks are sorted in 'order', either ascending
+  // or descending based on timestamp. If 'limit' is not set,
+  // default value 100 will be used.
   message GetTasks {
-    optional string limit = 1;
+    optional uint32 limit = 1 [default = 100];
     optional uint32 offset = 2;
     optional string order = 3;
   }