This is an automated email from the ASF dual-hosted git repository.

gilbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 114569fed4f92f7394e4a8aad7077b7084bb94e9
Author: Qian Zhang <[email protected]>
AuthorDate: Wed Feb 27 22:22:41 2019 -0800

    Added a test `UNPRIVILEGED_USER_SharedPersistentVolume`.
    
    Review: https://reviews.apache.org/r/68163/
---
 src/tests/persistent_volume_tests.cpp | 115 ++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/src/tests/persistent_volume_tests.cpp 
b/src/tests/persistent_volume_tests.cpp
index 6afc56c..8a5672e 100644
--- a/src/tests/persistent_volume_tests.cpp
+++ b/src/tests/persistent_volume_tests.cpp
@@ -2499,6 +2499,121 @@ TEST_P(PersistentVolumeTest, 
SharedPersistentVolumeMultipleFrameworks)
 }
 
 
+// This test verifies that a command task launched with a non-root user
+// can write to a shared persistent volume. We have a similar test in
+// linux_filesystem_isolator_tests.cpp which tests the implementation of
+// `filesystem/linux` isolator, and this one tests the implementation of
+// `filesystem/posix` isolator.
+TEST_P(PersistentVolumeTest, UNPRIVILEGED_USER_SharedPersistentVolume)
+{
+  Clock::pause();
+
+  master::Flags masterFlags = CreateMasterFlags();
+  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
+  ASSERT_SOME(master);
+
+  slave::Flags slaveFlags = CreateSlaveFlags();
+  slaveFlags.volume_gid_range = "[10000-20000]";
+
+  // Agent's work directory and `diskPath` are created with the
+  // mode 0700, here we change their modes to 0711 to ensure the
+  // non-root user used to launch the command task can enter it.
+  ASSERT_SOME(os::chmod(slaveFlags.work_dir, 0711));
+  ASSERT_SOME(os::chmod(diskPath, 0711));
+
+  slaveFlags.resources = getSlaveResources();
+
+  Future<UpdateSlaveMessage> updateSlaveMessage =
+    FUTURE_PROTOBUF(UpdateSlaveMessage(), _, _);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags);
+  ASSERT_SOME(slave);
+
+  Clock::advance(slaveFlags.registration_backoff_factor);
+  Clock::settle();
+  AWAIT_READY(updateSlaveMessage);
+
+  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+  frameworkInfo.set_roles(0, DEFAULT_TEST_ROLE);
+  frameworkInfo.add_capabilities()->set_type(
+      FrameworkInfo::Capability::SHARED_RESOURCES);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  EXPECT_CALL(sched, registered(&driver, _, _));
+
+  Future<vector<Offer>> offers1;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers1))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  Clock::advance(masterFlags.allocation_interval);
+
+  AWAIT_READY(offers1);
+  ASSERT_FALSE(offers1->empty());
+
+  Offer offer1 = offers1.get()[0];
+
+  // Create a shared volume, and launch a task to write a file to the volume.
+  Resource volume = createPersistentVolume(
+      getDiskResource(Megabytes(2048)),
+      "id1",
+      "path1",
+      None(),
+      frameworkInfo.principal(),
+      true); // Shared volume.
+
+  Option<string> user = os::getenv("SUDO_USER");
+  ASSERT_SOME(user);
+
+  CommandInfo command = createCommandInfo(
+        "echo hello > path1/file");
+
+  command.set_user(user.get());
+
+  TaskInfo task = createTask(
+      offer1.slave_id(),
+      Resources::parse("cpus:1;mem:128").get() + volume,
+      command);
+
+  // We should receive a TASK_STARTING, a TASK_RUNNING
+  // and a TASK_FINISHED for the launched task.
+  Future<TaskStatus> status0;
+  Future<TaskStatus> status1;
+  Future<TaskStatus> status2;
+
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&status0))
+    .WillOnce(FutureArg<1>(&status1))
+    .WillOnce(FutureArg<1>(&status2));
+
+  driver.acceptOffers(
+      {offer1.id()},
+      {CREATE(volume),
+       LAUNCH({task})});
+
+  AWAIT_READY(status0);
+  EXPECT_EQ(TASK_STARTING, status0->state());
+
+  AWAIT_READY(status1);
+  EXPECT_EQ(TASK_RUNNING, status1->state());
+
+  AWAIT_READY(status2);
+  EXPECT_EQ(TASK_FINISHED, status2->state());
+
+  // Resume the clock so the terminating task and executor can be reaped.
+  Clock::resume();
+
+  driver.stop();
+  driver.join();
+}
+
+
 // This test verifies that the master recovers after a failover and
 // re-offers the shared persistent volume when tasks using the same
 // volume are still running.

Reply via email to