// Ensures that the driver can handle the SUBSCRIBED event. TEST_F(SchedulerDriverEventTest, Subscribed) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); // Make sure the initial registration calls 'registered'. MockScheduler sched; MesosSchedulerDriver driver( &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL); // Intercept the registration message, send a SUBSCRIBED instead. Future<Message> frameworkRegisteredMessage = DROP_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); // Ensure that there will be no (re-)registration retries // from the scheduler driver. Clock::pause(); driver.start(); AWAIT_READY(frameworkRegisteredMessage); UPID frameworkPid = frameworkRegisteredMessage.get().to; FrameworkRegisteredMessage message; ASSERT_TRUE(message.ParseFromString(frameworkRegisteredMessage.get().body)); FrameworkID frameworkId = message.framework_id(); frameworkInfo.mutable_id()->CopyFrom(frameworkId); Event event; event.set_type(Event::SUBSCRIBED); event.mutable_subscribed()->mutable_framework_id()->CopyFrom(frameworkId); Future<Nothing> registered; EXPECT_CALL(sched, registered(&driver, frameworkId, _)) .WillOnce(FutureSatisfy(®istered)); process::post(master.get()->pid, frameworkPid, event); AWAIT_READY(registered); driver.stop(); driver.join(); }
// This test verifies if the executor is able to receive a Subscribed // event in response to a Subscribe call request. TEST_P(ExecutorHttpApiTest, Subscribe) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); ExecutorID executorId = DEFAULT_EXECUTOR_ID; MockExecutor exec(executorId); TestContainerizer containerizer(&exec); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), &containerizer); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId)); Future<vector<Offer>> offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)); driver.start(); AWAIT_READY(frameworkId); AWAIT_READY(offers); ASSERT_EQ(1u, offers.get().size()); Future<Message> registerExecutorMessage = DROP_MESSAGE(Eq(RegisterExecutorMessage().GetTypeName()), _, _); TaskInfo taskInfo = createTask(offers.get()[0], "", executorId); driver.launchTasks(offers.get()[0].id(), {taskInfo}); // Drop the `RegisterExecutorMessage` and then send a `Subscribe` request // from the HTTP based executor. AWAIT_READY(registerExecutorMessage); Call call; call.mutable_framework_id()->CopyFrom(evolve(frameworkId.get())); call.mutable_executor_id()->CopyFrom(evolve(executorId)); call.set_type(Call::SUBSCRIBE); call.mutable_subscribe(); // Retrieve the parameter passed as content type to this test. const ContentType contentType = GetParam(); const string contentTypeString = stringify(contentType); process::http::Headers headers; headers["Accept"] = contentTypeString; Future<Response> response = process::http::streaming::post( slave.get()->pid, "api/v1/executor", headers, serialize(contentType, call), contentTypeString); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); AWAIT_EXPECT_RESPONSE_HEADER_EQ("chunked", "Transfer-Encoding", response); AWAIT_EXPECT_RESPONSE_HEADER_EQ(contentTypeString, "Content-Type", response); ASSERT_EQ(Response::PIPE, response.get().type); Option<Pipe::Reader> reader = response.get().reader; ASSERT_SOME(reader); auto deserializer = lambda::bind(deserialize<Event>, contentType, lambda::_1); Reader<Event> responseDecoder( Decoder<Event>(deserializer), reader.get()); Future<Result<Event>> event = responseDecoder.read(); AWAIT_READY(event); ASSERT_SOME(event.get()); // Check event type is subscribed and if the ExecutorID matches. ASSERT_EQ(Event::SUBSCRIBED, event.get().get().type()); ASSERT_EQ(event.get().get().subscribed().executor_info().executor_id(), call.executor_id()); reader.get().close(); driver.stop(); driver.join(); }
// Ensures that the driver can handle the SUBSCRIBED event // after a master failover. TEST_F(SchedulerDriverEventTest, SubscribedMasterFailover) { Try<PID<Master>> master = StartMaster(); ASSERT_SOME(master); FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_failover_timeout(Weeks(2).secs()); // Make sure the initial registration calls 'registered'. MockScheduler sched; StandaloneMasterDetector detector(master.get()); TestingMesosSchedulerDriver driver(&sched, &detector, frameworkInfo); // Intercept the registration message, send a SUBSCRIBED instead. Future<Message> frameworkRegisteredMessage = DROP_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); // Ensure that there will be no (re-)registration retries // from the scheduler driver. Clock::pause(); driver.start(); AWAIT_READY(frameworkRegisteredMessage); UPID frameworkPid = frameworkRegisteredMessage.get().to; FrameworkRegisteredMessage message; ASSERT_TRUE(message.ParseFromString(frameworkRegisteredMessage.get().body)); FrameworkID frameworkId = message.framework_id(); frameworkInfo.mutable_id()->CopyFrom(frameworkId); Event event; event.set_type(Event::SUBSCRIBED); event.mutable_subscribed()->mutable_framework_id()->CopyFrom(frameworkId); Future<Nothing> registered; EXPECT_CALL(sched, registered(&driver, frameworkId, _)) .WillOnce(FutureSatisfy(®istered)); process::post(master.get(), frameworkPid, event); AWAIT_READY(registered); // Fail over the master and expect a 'reregistered' call. // Note that the master sends a registered message for // this case (see MESOS-786). Stop(master.get()); master = StartMaster(); ASSERT_SOME(master); EXPECT_CALL(sched, disconnected(&driver)); frameworkRegisteredMessage = DROP_MESSAGE(Eq(FrameworkRegisteredMessage().GetTypeName()), _, _); detector.appoint(master.get()); AWAIT_READY(frameworkRegisteredMessage); Future<Nothing> reregistered; EXPECT_CALL(sched, reregistered(&driver, _)) .WillOnce(FutureSatisfy(&reregistered)); process::post(master.get(), frameworkPid, event); AWAIT_READY(reregistered); }