TYPED_TEST(AuthorizationTest, NoPrincipalRunAsUser) { // No principal can run as "root" user. ACLs acls; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_users()->add_values("root"); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" cannot run as "root". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("root"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request)); }
TYPED_TEST(AuthorizationTest, AnyPrincipalOfferedRole) { // Any principal can be offered "*" role's resources. ACLs acls; mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl->mutable_roles()->add_values("*"); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principals "foo" and "bar" can be offered "*" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_principals()->add_values("bar"); request.mutable_roles()->add_values("*"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); }
TYPED_TEST(AuthorizationTest, AnyPrincipalRunAsAnyUser) { // Any principal can run as any user. ACLs acls; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principals "foo" and "bar" can run as "user1" and "user2". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_principals()->add_values("bar"); request.mutable_users()->add_values("user1"); request.mutable_users()->add_values("user2"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); }
// This test ensures that destroy can be called while in the // launch loop. The composing containerizer still calls the // underlying containerizer's destroy (because it's not sure // if the containerizer can handle the type of container being // launched). If the launch is not supported by the 1st containerizer, // the composing containerizer should stop the launch loop and // set the value of destroy future to true. TEST_F(ComposingContainerizerTest, DestroyDuringUnsupportedLaunchLoop) { vector<Containerizer*> containerizers; MockContainerizer* mockContainerizer1 = new MockContainerizer(); MockContainerizer* mockContainerizer2 = new MockContainerizer(); containerizers.push_back(mockContainerizer1); containerizers.push_back(mockContainerizer2); ComposingContainerizer containerizer(containerizers); ContainerID containerId; containerId.set_value("container"); TaskInfo taskInfo; ExecutorInfo executorInfo; SlaveID slaveId; std::map<std::string, std::string> environment; Promise<bool> launchPromise; EXPECT_CALL(*mockContainerizer1, launch(_, _, _, _, _, _, _, _)) .WillOnce(Return(launchPromise.future())); Future<Nothing> destroy; Promise<bool> destroyPromise; EXPECT_CALL(*mockContainerizer1, destroy(_)) .WillOnce(DoAll(FutureSatisfy(&destroy), Return(destroyPromise.future()))); Future<bool> launched = containerizer.launch( containerId, taskInfo, executorInfo, "dir", "user", slaveId, environment, false); Resources resources = Resources::parse("cpus:1;mem:256").get(); EXPECT_TRUE(launched.isPending()); Future<bool> destroyed = containerizer.destroy(containerId); EXPECT_CALL(*mockContainerizer2, launch(_, _, _, _, _, _, _, _)) .Times(0); // We make sure the destroy is being called on the first containerizer. // The second containerizer shouldn't be called as well since the // container is already destroyed. AWAIT_READY(destroy); launchPromise.set(false); destroyPromise.set(false); // `launched` should be a failure and `destroyed` should be true // because the launch was stopped from being tried on the 2nd // containerizer because of the destroy. AWAIT_FAILED(launched); AWAIT_EXPECT_EQ(true, destroyed); }
// Ensures that the driver can handle an OFFERS event. // Note that this includes the ability to bypass the // master when sending framework messages. TEST_F(SchedulerDriverEventTest, Offers) { Try<PID<Master>> master = StartMaster(); ASSERT_SOME(master); MockScheduler sched; MesosSchedulerDriver schedDriver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&schedDriver, _, _)); Future<Message> frameworkRegisteredMessage = FUTURE_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); schedDriver.start(); AWAIT_READY(frameworkRegisteredMessage); UPID frameworkPid = frameworkRegisteredMessage.get().to; // Start a slave and capture the offers. Future<ResourceOffersMessage> resourceOffersMessage = DROP_PROTOBUF(ResourceOffersMessage(), _, _); MockExecutor exec(DEFAULT_EXECUTOR_ID); Try<PID<Slave>> slave = StartSlave(&exec); ASSERT_SOME(slave); AWAIT_READY(resourceOffersMessage); google::protobuf::RepeatedPtrField<Offer> offers = resourceOffersMessage.get().offers(); ASSERT_EQ(1, offers.size()); // Ignore future offer messages. DROP_PROTOBUFS(ResourceOffersMessage(), _, _); // Send the offers event and expect a 'resourceOffers' call. Event event; event.set_type(Event::OFFERS); event.mutable_offers()->mutable_offers()->CopyFrom(offers); Future<Nothing> resourceOffers; EXPECT_CALL(sched, resourceOffers(&schedDriver, _)) .WillOnce(FutureSatisfy(&resourceOffers)); process::post(master.get(), frameworkPid, event); AWAIT_READY(resourceOffers); // To test that the framework -> executor messages are // sent directly to the slave, launch a task and send // the executor a message. EXPECT_CALL(exec, registered(_, _, _, _)); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&schedDriver, _)) .WillOnce(FutureArg<1>(&status)); TaskInfo task = createTask(offers.Get(0), "", DEFAULT_EXECUTOR_ID); schedDriver.launchTasks(offers.Get(0).id(), {task}); AWAIT_READY(status); EXPECT_EQ(TASK_RUNNING, status.get().state()); // This message should skip the master! Future<FrameworkToExecutorMessage> frameworkToExecutorMessage = FUTURE_PROTOBUF(FrameworkToExecutorMessage(), frameworkPid, slave.get()); Future<string> data; EXPECT_CALL(exec, frameworkMessage(_, _)) .WillOnce(FutureArg<1>(&data)); schedDriver.sendFrameworkMessage( DEFAULT_EXECUTOR_ID, offers.Get(0).slave_id(), "hello"); AWAIT_READY(frameworkToExecutorMessage); AWAIT_EXPECT_EQ("hello", data); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); schedDriver.stop(); schedDriver.join(); Shutdown(); }