src/tests/persistent_volume_endpoints_tests.cpp
TEST_F(PersistentVolumeEndpointsTest, GoodCreateAndDestroyACL)
{
  // Pause the clock to gain control over the offer cycle.
  Clock::pause();

  TestAllocator<> allocator;
  ACLs acls;

  // This ACL asserts that the principal of `DEFAULT_CREDENTIAL`
  // can create volumes for any role.
  mesos::ACL::CreateVolume* create = acls.add_create_volumes();
  create->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal());
  create->mutable_roles()->set_type(mesos::ACL::Entity::ANY);

  // This ACL asserts that the principal of `DEFAULT_CREDENTIAL`
  // can destroy volumes that it created.
  mesos::ACL::DestroyVolume* destroy = acls.add_destroy_volumes();
  destroy->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal());
  destroy->mutable_creator_principals()->add_values(
      DEFAULT_CREDENTIAL.principal());

  // Create a master.
  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.acls = acls;

  EXPECT_CALL(allocator, initialize(_, _, _, _));

  Try<Owned<cluster::Master>> master = StartMaster(&allocator, masterFlags);
  ASSERT_SOME(master);

  // Create a slave. Disk resources are statically reserved to allow the
  // creation of a persistent volume.
  slave::Flags slaveFlags = CreateSlaveFlags();
  slaveFlags.resources = "cpus:1;mem:512;disk(role1):1024";

  Future<SlaveID> slaveId;
  EXPECT_CALL(allocator, addSlave(_, _, _, _, _))
    .WillOnce(DoAll(InvokeAddSlave(&allocator), FutureArg<0>(&slaveId)));

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags);
  ASSERT_SOME(slave);

  process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL);

  Resources volume = createPersistentVolume(
      Megabytes(64),
      "role1",
      "id1",
      "path1");

  Future<Response> createResponse = process::http::post(
      master.get()->pid,
      "create-volumes",
      createBasicAuthHeaders(DEFAULT_CREDENTIAL),
      createRequestBody(slaveId.get(), "volumes", volume));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, createResponse);

  FrameworkInfo frameworkInfo = createFrameworkInfo();

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<vector<Offer>> offers;

  EXPECT_CALL(sched, registered(&driver, _, _));

  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));

  driver.start();

  Clock::settle();
  Clock::advance(DEFAULT_ALLOCATION_INTERVAL);

  AWAIT_READY(offers);

  ASSERT_EQ(1u, offers.get().size());
  Offer offer = offers.get()[0];

  EXPECT_TRUE(Resources(offer.resources()).contains(volume));

  Future<OfferID> rescindedOfferId;

  EXPECT_CALL(sched, offerRescinded(&driver, _))
    .WillOnce(FutureArg<1>(&rescindedOfferId));

  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));

  Future<Response> destroyResponse = process::http::post(
      master.get()->pid,
      "destroy-volumes",
      createBasicAuthHeaders(DEFAULT_CREDENTIAL),
      createRequestBody(slaveId.get(), "volumes", volume));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, destroyResponse);

  Clock::settle();
  Clock::advance(DEFAULT_ALLOCATION_INTERVAL);

  AWAIT_READY(rescindedOfferId);

  EXPECT_EQ(rescindedOfferId.get(), offer.id());

  AWAIT_READY(offers);

  ASSERT_EQ(1u, offers.get().size());
  offer = offers.get()[0];

  EXPECT_FALSE(Resources(offer.resources()).contains(volume));

  driver.stop();
  driver.join();
}
// This tests that correct setup of CreateVolume/DestroyVolume ACLs allows an
// operator to perform volume creation/destruction operations successfully.
This tests that correct setup of CreateVolume/DestroyVolume ACLs allows an
operator to perform volume creation/destruction operations successfully.
This tests that correct setup of CreateVolume / DestroyVolume ACLs allows an operator to perform volume creation / destruction operations successfully .
TEST_F(PersistentVolumeEndpointsTest, GoodCreateAndDestroyACL)
{
  Clock::pause();
  TestAllocator<> allocator;
  ACLs acls;
  mesos::ACL::CreateVolume* create = acls.add_create_volumes();
  create->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal());
  create->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
  mesos::ACL::DestroyVolume* destroy = acls.add_destroy_volumes();
  destroy->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal());
  destroy->mutable_creator_principals()->add_values(
      DEFAULT_CREDENTIAL.principal());
  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.acls = acls;
  EXPECT_CALL(allocator, initialize(_, _, _, _));
  Try<Owned<cluster::Master>> master = StartMaster(&allocator, masterFlags);
  ASSERT_SOME(master);
  slave::Flags slaveFlags = CreateSlaveFlags();
  slaveFlags.resources = "cpus:1;mem:512;disk(role1):1024";
  Future<SlaveID> slaveId;
  EXPECT_CALL(allocator, addSlave(_, _, _, _, _))
    .WillOnce(DoAll(InvokeAddSlave(&allocator), FutureArg<0>(&slaveId)));
  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags);
  ASSERT_SOME(slave);
  process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL);
  Resources volume = createPersistentVolume(
      Megabytes(64),
      "role1",
      "id1",
      "path1");
  Future<Response> createResponse = process::http::post(
      master.get()->pid,
      "create-volumes",
      createBasicAuthHeaders(DEFAULT_CREDENTIAL),
      createRequestBody(slaveId.get(), "volumes", volume));
  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, createResponse);
  FrameworkInfo frameworkInfo = createFrameworkInfo();
  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
  Future<vector<Offer>> offers;
  EXPECT_CALL(sched, registered(&driver, _, _));
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));
  driver.start();
  Clock::settle();
  Clock::advance(DEFAULT_ALLOCATION_INTERVAL);
  AWAIT_READY(offers);
  ASSERT_EQ(1u, offers.get().size());
  Offer offer = offers.get()[0];
  EXPECT_TRUE(Resources(offer.resources()).contains(volume));
  Future<OfferID> rescindedOfferId;
  EXPECT_CALL(sched, offerRescinded(&driver, _))
    .WillOnce(FutureArg<1>(&rescindedOfferId));
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));
  Future<Response> destroyResponse = process::http::post(
      master.get()->pid,
      "destroy-volumes",
      createBasicAuthHeaders(DEFAULT_CREDENTIAL),
      createRequestBody(slaveId.get(), "volumes", volume));
  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, destroyResponse);
  Clock::settle();
  Clock::advance(DEFAULT_ALLOCATION_INTERVAL);
  AWAIT_READY(rescindedOfferId);
  EXPECT_EQ(rescindedOfferId.get(), offer.id());
  AWAIT_READY(offers);
  ASSERT_EQ(1u, offers.get().size());
  offer = offers.get()[0];
  EXPECT_FALSE(Resources(offer.resources()).contains(volume));
  driver.stop();
  driver.join();
}
TEST_F ( PersistentVolumeEndpointsTest , GoodCreateAndDestroyACL ) { Clock :: pause ( ) ; TestAllocator < > allocator ; ACLs acls ; mesos :: ACL :: CreateVolume * create = acls . add_create_volumes ( ) ; create -> mutable_principals ( ) -> add_values ( DEFAULT_CREDENTIAL . principal ( ) ) ; create -> mutable_roles ( ) -> set_type ( mesos :: ACL :: Entity :: ANY ) ; mesos :: ACL :: DestroyVolume * destroy = acls . add_destroy_volumes ( ) ; destroy -> mutable_principals ( ) -> add_values ( DEFAULT_CREDENTIAL . principal ( ) ) ; destroy -> mutable_creator_principals ( ) -> add_values ( DEFAULT_CREDENTIAL . principal ( ) ) ; master :: Flags masterFlags = CreateMasterFlags ( ) ; masterFlags . acls = acls ; EXPECT_CALL ( allocator , initialize ( _ , _ , _ , _ ) ) ; Try < Owned < cluster :: Master > > master = StartMaster ( & allocator , masterFlags ) ; ASSERT_SOME ( master ) ; slave :: Flags slaveFlags = CreateSlaveFlags ( ) ; slaveFlags . resources = " " ; Future < SlaveID > slaveId ; EXPECT_CALL ( allocator , addSlave ( _ , _ , _ , _ , _ ) ) . WillOnce ( DoAll ( InvokeAddSlave ( & allocator ) , FutureArg < 0 > ( & slaveId ) ) ) ; Owned < MasterDetector > detector = master . get ( ) -> createDetector ( ) ; Try < Owned < cluster :: Slave > > slave = StartSlave ( detector . get ( ) , slaveFlags ) ; ASSERT_SOME ( slave ) ; process :: http :: Headers headers = createBasicAuthHeaders ( DEFAULT_CREDENTIAL ) ; Resources volume = createPersistentVolume ( Megabytes ( 64 ) , " " , " " , " " ) ; Future < Response > createResponse = process :: http :: post ( master . get ( ) -> pid , " " , createBasicAuthHeaders ( DEFAULT_CREDENTIAL ) , createRequestBody ( slaveId . get ( ) , " " , volume ) ) ; AWAIT_EXPECT_RESPONSE_STATUS_EQ ( OK ( ) . status , createResponse ) ; FrameworkInfo frameworkInfo = createFrameworkInfo ( ) ; MockScheduler sched ; MesosSchedulerDriver driver ( & sched , frameworkInfo , master . get ( ) -> pid , DEFAULT_CREDENTIAL ) ; Future < vector < Offer > > offers ; EXPECT_CALL ( sched , registered ( & driver , _ , _ ) ) ; EXPECT_CALL ( sched , resourceOffers ( & driver , _ ) ) . WillOnce ( FutureArg < 1 > ( & offers ) ) ; driver . start ( ) ; Clock :: settle ( ) ; Clock :: advance ( DEFAULT_ALLOCATION_INTERVAL ) ; AWAIT_READY ( offers ) ; ASSERT_EQ ( 1u , offers . get ( ) . size ( ) ) ; Offer offer = offers . get ( ) [ 0 ] ; EXPECT_TRUE ( Resources ( offer . resources ( ) ) . contains ( volume ) ) ; Future < OfferID > rescindedOfferId ; EXPECT_CALL ( sched , offerRescinded ( & driver , _ ) ) . WillOnce ( FutureArg < 1 > ( & rescindedOfferId ) ) ; EXPECT_CALL ( sched , resourceOffers ( & driver , _ ) ) . WillOnce ( FutureArg < 1 > ( & offers ) ) ; Future < Response > destroyResponse = process :: http :: post ( master . get ( ) -> pid , " " , createBasicAuthHeaders ( DEFAULT_CREDENTIAL ) , createRequestBody ( slaveId . get ( ) , " " , volume ) ) ; AWAIT_EXPECT_RESPONSE_STATUS_EQ ( OK ( ) . status , destroyResponse ) ; Clock :: settle ( ) ; Clock :: advance ( DEFAULT_ALLOCATION_INTERVAL ) ; AWAIT_READY ( rescindedOfferId ) ; EXPECT_EQ ( rescindedOfferId . get ( ) , offer . id ( ) ) ; AWAIT_READY ( offers ) ; ASSERT_EQ ( 1u , offers . get ( ) . size ( ) ) ; offer = offers . get ( ) [ 0 ] ; EXPECT_FALSE ( Resources ( offer . resources ( ) ) . contains ( volume ) ) ; driver . stop ( ) ; driver . join ( ) ; }
This tests that correct setup of CreateVolume/DestroyVolume ACLs allows an
operator to perform volume creation/destruction operations successfully.
This tests that correct setup of CreateVolume / DestroyVolume ACLs allows an operator to perform volume creation / destruction operations successfully .
// Pause the clock to gain control over the offer cycle. // This ACL asserts that the principal of `DEFAULT_CREDENTIAL` // can create volumes for any role. // This ACL asserts that the principal of `DEFAULT_CREDENTIAL` // can destroy volumes that it created. // Create a master. // Create a slave. Disk resources are statically reserved to allow the // creation of a persistent volume.