Repository: mesos
Updated Branches:
  refs/heads/master 776bfab96 -> c4c821ca5


Added a test `CgroupsIsolatorTest.ROOT_CGROUPS_BlkioUsage`.

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


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

Branch: refs/heads/master
Commit: c4c821ca508bfefd6dd29469306660c6359c9feb
Parents: 776bfab
Author: Qian Zhang <zhq527...@gmail.com>
Authored: Mon Nov 13 16:28:30 2017 -0800
Committer: Gilbert Song <songzihao1...@gmail.com>
Committed: Mon Nov 13 16:28:30 2017 -0800

----------------------------------------------------------------------
 .../containerizer/cgroups_isolator_tests.cpp    | 163 +++++++++++++++++++
 1 file changed, 163 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/c4c821ca/src/tests/containerizer/cgroups_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/cgroups_isolator_tests.cpp 
b/src/tests/containerizer/cgroups_isolator_tests.cpp
index aad3f53..421a72f 100644
--- a/src/tests/containerizer/cgroups_isolator_tests.cpp
+++ b/src/tests/containerizer/cgroups_isolator_tests.cpp
@@ -1620,6 +1620,169 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryBackward)
   driver.join();
 }
 
+
+// This test verifies the cgroups blkio statistics
+// of the container can be successfully retrieved.
+TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_BlkioUsage)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.isolation = "cgroups/blkio";
+
+  Fetcher fetcher(flags);
+
+  Try<MesosContainerizer*> _containerizer =
+    MesosContainerizer::create(flags, true, &fetcher);
+
+  ASSERT_SOME(_containerizer);
+
+  Owned<MesosContainerizer> containerizer(_containerizer.get());
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+
+  Try<Owned<cluster::Slave>> slave = StartSlave(
+      detector.get(),
+      containerizer.get(),
+      flags);
+
+  ASSERT_SOME(slave);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched,
+      DEFAULT_FRAMEWORK_INFO,
+      master.get()->pid,
+      DEFAULT_CREDENTIAL);
+
+  EXPECT_CALL(sched, registered(&driver, _, _));
+
+  Future<vector<Offer>> offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(offers);
+  ASSERT_FALSE(offers->empty());
+
+  // Create a task to generate a 10k file with 10 disk writes.
+  //
+  // TODO(qianzhang): In some old platforms (CentOS 6 and Ubuntu 14),
+  // the first disk write of a blkio cgroup will always be missed in
+  // the blkio throttling statistics, so here we run two `dd` commands,
+  // the first one which does the first disk write will be missed on
+  // those platforms, and the second one will be recorded in the blkio
+  // throttling statistics. When we drop the CentOS 6 and Ubuntu 14
+  // support, we should remove the first `dd` command.
+  TaskInfo task = createTask(
+      offers.get()[0],
+      "dd if=/dev/zero of=file bs=1024 count=1 oflag=dsync && "
+      "dd if=/dev/zero of=file bs=1024 count=10 oflag=dsync && "
+      "sleep 1000");
+
+  Future<TaskStatus> statusStarting;
+  Future<TaskStatus> statusRunning;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillRepeatedly(Return());
+
+  driver.launchTasks(offers.get()[0].id(), {task});
+
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
+  AWAIT_READY(statusRunning);
+  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+  // NOTE: The command executor's id is the same as the task id.
+  ExecutorID executorId;
+  executorId.set_value(task.task_id().value());
+
+  const string directory = slave::paths::getExecutorLatestRunPath(
+      flags.work_dir,
+      offers.get()[0].slave_id(),
+      offers.get()[0].framework_id(),
+      executorId);
+
+  ASSERT_TRUE(os::exists(directory));
+
+  // Make sure the file is completely generated.
+  const string filePath = path::join(directory, "file");
+  Option<Bytes> fileSize;
+  Duration waited = Duration::zero();
+
+  do {
+    if (os::exists(filePath)) {
+      Try<Bytes> size = os::stat::size(filePath);
+      ASSERT_SOME(size);
+
+      if (size->bytes() == 10240) {
+        fileSize = size.get();
+        break;
+      }
+    }
+
+    os::sleep(Seconds(1));
+    waited += Seconds(1);
+  } while (waited < Seconds(15));
+
+  ASSERT_SOME(fileSize);
+  ASSERT_EQ(10240u, fileSize->bytes());
+
+  Future<hashset<ContainerID>> containers = containerizer->containers();
+  AWAIT_READY(containers);
+  ASSERT_EQ(1u, containers->size());
+
+  ContainerID containerId = *(containers->begin());
+
+  Future<ResourceStatistics> usage = containerizer->usage(containerId);
+  AWAIT_READY(usage);
+
+  // We only check throttling statistics but not cfq statistics, because
+  // in the environment where the disk IO scheduler is not cfq, all the
+  // cfq statistics may be 0. And there must be at least two entries in
+  // the throttling statistics, one is the total statistics, the others
+  // are device specific statistics.
+  EXPECT_TRUE(usage->has_blkio_statistics());
+  EXPECT_LE(2, usage->blkio_statistics().throttling_size());
+
+  // We only check the total throttling statistics.
+  Option<CgroupInfo::Blkio::Throttling::Statistics> totalThrottling;
+  foreach (const CgroupInfo::Blkio::Throttling::Statistics& statistics,
+           usage->blkio_statistics().throttling()) {
+    if (!statistics.has_device()) {
+      totalThrottling = statistics;
+    }
+  }
+
+  EXPECT_SOME(totalThrottling);
+  EXPECT_EQ(1, totalThrottling->io_serviced_size());
+  EXPECT_EQ(1, totalThrottling->io_service_bytes_size());
+
+  const CgroupInfo::Blkio::Value& totalIOServiced =
+      totalThrottling->io_serviced(0);
+
+  EXPECT_TRUE(totalIOServiced.has_op());
+  EXPECT_EQ(CgroupInfo::Blkio::TOTAL, totalIOServiced.op());
+  EXPECT_TRUE(totalIOServiced.has_value());
+  EXPECT_LE(10u, totalIOServiced.value());
+
+  const CgroupInfo::Blkio::Value& totalIOServiceBytes =
+      totalThrottling->io_service_bytes(0);
+
+  EXPECT_TRUE(totalIOServiceBytes.has_op());
+  EXPECT_EQ(CgroupInfo::Blkio::TOTAL, totalIOServiceBytes.op());
+  EXPECT_TRUE(totalIOServiceBytes.has_value());
+  EXPECT_LE(10240u, totalIOServiceBytes.value());
+
+  driver.stop();
+  driver.join();
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

Reply via email to