Skip to content
This repository was archived by the owner on Oct 23, 2024. It is now read-only.

Commit f284314

Browse files
committed
Added a scheduler API test for a valid offer constraints update.
Review: https://reviews.apache.org/r/72744
1 parent 04599f9 commit f284314

File tree

1 file changed

+106
-1
lines changed

1 file changed

+106
-1
lines changed

src/tests/master/update_framework_tests.cpp

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ class UpdateFrameworkTest : public MesosTest {};
193193
static Future<APIResult> callUpdateFramework(
194194
Mesos* mesos,
195195
const FrameworkInfo& info,
196-
const vector<string>& suppressedRoles = {})
196+
const vector<string>& suppressedRoles = {},
197+
const Option<::mesos::v1::scheduler::OfferConstraints>& offerConstraints =
198+
None())
197199
{
198200
CHECK(info.has_id());
199201

@@ -203,6 +205,12 @@ static Future<APIResult> callUpdateFramework(
203205
*call.mutable_update_framework()->mutable_framework_info() = info;
204206
*call.mutable_update_framework()->mutable_suppressed_roles() =
205207
RepeatedPtrField<string>(suppressedRoles.begin(), suppressedRoles.end());
208+
209+
if (offerConstraints.isSome()) {
210+
*call.mutable_update_framework()->mutable_offer_constraints() =
211+
*offerConstraints;
212+
}
213+
206214
return mesos->call(call);
207215
}
208216

@@ -725,6 +733,103 @@ TEST_F(UpdateFrameworkTest, RemoveAndUnsuppress)
725733
}
726734

727735

736+
// This test ensures that it is possible to modify offer constraints
737+
// via the UpdateFramework call.
738+
TEST_F(UpdateFrameworkTest, OfferConstraints)
739+
{
740+
using ::mesos::v1::scheduler::AttributeConstraint;
741+
using ::mesos::v1::scheduler::OfferConstraints;
742+
743+
mesos::internal::master::Flags masterFlags = CreateMasterFlags();
744+
Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
745+
ASSERT_SOME(master);
746+
747+
Owned<MasterDetector> detector = master->get()->createDetector();
748+
749+
mesos::internal::slave::Flags slaveFlags = CreateSlaveFlags();
750+
Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags);
751+
ASSERT_SOME(slave);
752+
753+
auto scheduler = std::make_shared<MockHTTPScheduler>();
754+
755+
EXPECT_CALL(*scheduler, connected(_))
756+
.WillOnce(Invoke([](Mesos* mesos) {
757+
Call call;
758+
call.set_type(Call::SUBSCRIBE);
759+
*call.mutable_subscribe()->mutable_framework_info() =
760+
DEFAULT_FRAMEWORK_INFO;
761+
762+
AttributeConstraint* constraint =
763+
(*call.mutable_subscribe()
764+
->mutable_offer_constraints()
765+
->mutable_role_constraints())[DEFAULT_FRAMEWORK_INFO.roles(0)]
766+
.add_groups()
767+
->add_attribute_constraints();
768+
769+
*constraint->mutable_selector()->mutable_attribute_name() = "foo";
770+
*constraint->mutable_predicate()->mutable_exists() =
771+
AttributeConstraint::Predicate::Exists();
772+
773+
mesos->send(call);
774+
}));
775+
776+
EXPECT_CALL(*scheduler, heartbeat(_))
777+
.WillRepeatedly(Return()); // Ignore heartbeats.
778+
779+
Future<Event::Subscribed> subscribed;
780+
781+
EXPECT_CALL(*scheduler, subscribed(_, _)).WillOnce(FutureArg<1>(&subscribed));
782+
783+
// Expect that the framework gets no offers.
784+
EXPECT_CALL(*scheduler, offers(_, _)).Times(AtMost(0));
785+
786+
TestMesos mesos(master->get()->pid, ContentType::PROTOBUF, scheduler);
787+
788+
AWAIT_READY(subscribed);
789+
790+
// Trigger allocation to ensure that the agent is not offered before changing
791+
// offer constraints.
792+
Clock::pause();
793+
Clock::settle();
794+
Clock::advance(masterFlags.allocation_interval);
795+
Clock::settle();
796+
797+
// Expect an offer after constraints change.
798+
Future<Event::Offers> offers;
799+
EXPECT_CALL(*scheduler, offers(_, _)).WillOnce(FutureArg<1>(&offers));
800+
801+
// Change constraint to `NotExists` so that the agent will now be offered to
802+
// the framework.
803+
{
804+
FrameworkInfo framework = DEFAULT_FRAMEWORK_INFO;
805+
*framework.mutable_id() = subscribed->framework_id();
806+
807+
OfferConstraints constraints;
808+
AttributeConstraint* constraint =
809+
(*constraints.mutable_role_constraints())[framework.roles(0)]
810+
.add_groups()
811+
->add_attribute_constraints();
812+
813+
*constraint->mutable_selector()->mutable_attribute_name() = "foo";
814+
*constraint->mutable_predicate()->mutable_not_exists() =
815+
AttributeConstraint::Predicate::NotExists();
816+
817+
AWAIT_READY(callUpdateFramework(&mesos, framework, {}, constraints));
818+
}
819+
820+
Clock::pause();
821+
Clock::settle();
822+
Clock::advance(masterFlags.allocation_interval);
823+
Clock::settle();
824+
825+
AWAIT_READY(offers);
826+
EXPECT_EQ(offers->offers().size(), 1);
827+
828+
// TODO(asekretenko): After master starts exposing offer constraints via
829+
// its endpoints (MESOS-10179), check the constraints in the endpoints.
830+
}
831+
832+
728833
} // namespace scheduler {
729834
} // namespace v1 {
730835

0 commit comments

Comments
 (0)