// Using JSON base file for authentication without // protobuf tools assistance. TEST_F(CredentialsTest, AuthenticatedSlaveJSON) { string path = path::join(os::getcwd(), "credentials"); Try<int_fd> fd = os::open( path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP); ASSERT_SOME(fd); // This unit tests our capacity to process JSON credentials without // using our protobuf tools. JSON::Object credential; credential.values["principal"] = DEFAULT_CREDENTIAL.principal(); credential.values["secret"] = DEFAULT_CREDENTIAL.secret(); JSON::Array array; array.values.push_back(credential); JSON::Object credentials; credentials.values["credentials"] = array; ASSERT_SOME(os::write(fd.get(), stringify(credentials))) << "Failed to write credentials to '" << path << "'"; ASSERT_SOME(os::close(fd.get())); map<string, Option<string>> values{ {"credentials", Some(uri::from_path(path))}}; master::Flags masterFlags = CreateMasterFlags(); masterFlags.load(values, true); Try<Owned<cluster::Master>> master = StartMaster(masterFlags); ASSERT_SOME(master); Future<SlaveRegisteredMessage> slaveRegisteredMessage = FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _); slave::Flags slaveFlags = CreateSlaveFlags(); slaveFlags.load(values, true); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags); ASSERT_SOME(slave); AWAIT_READY(slaveRegisteredMessage); ASSERT_NE("", slaveRegisteredMessage->slave_id().value()); }
// This test verifies that an authenticated slave is // granted registration by the master. TEST_F(CredentialsTest, AuthenticatedSlave) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); Future<SlaveRegisteredMessage> slaveRegisteredMessage = FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get()); ASSERT_SOME(slave); AWAIT_READY(slaveRegisteredMessage); ASSERT_NE("", slaveRegisteredMessage->slave_id().value()); }
// Test verifing well executed credential authentication // using text formatted credentials so as to test // backwards compatibility. TEST_F(CredentialsTest, AuthenticatedSlaveText) { string path = path::join(os::getcwd(), "credentials"); Try<int_fd> fd = os::open( path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP); ASSERT_SOME(fd); string credentials = DEFAULT_CREDENTIAL.principal() + " " + DEFAULT_CREDENTIAL.secret(); ASSERT_SOME(os::write(fd.get(), credentials)) << "Failed to write credentials to '" << path << "'"; ASSERT_SOME(os::close(fd.get())); map<string, Option<string>> values{ {"credentials", Some(uri::from_path(path))}}; master::Flags masterFlags = CreateMasterFlags(); masterFlags.load(values, true); Try<Owned<cluster::Master>> master = StartMaster(masterFlags); ASSERT_SOME(master); Future<SlaveRegisteredMessage> slaveRegisteredMessage = FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _); slave::Flags slaveFlags = CreateSlaveFlags(); slaveFlags.load(values, true); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags); ASSERT_SOME(slave); AWAIT_READY(slaveRegisteredMessage); ASSERT_NE("", slaveRegisteredMessage->slave_id().value()); }
// This test verifies that reconciliation of an unknown operation that belongs // to an agent marked gone results in `OPERATION_GONE_BY_OPERATOR`. TEST_P(OperationReconciliationTest, UnknownOperationAgentMarkedGone) { Clock::pause(); mesos::internal::master::Flags masterFlags = CreateMasterFlags(); Try<Owned<cluster::Master>> master = StartMaster(masterFlags); ASSERT_SOME(master); Future<SlaveRegisteredMessage> slaveRegisteredMessage = FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _); Owned<MasterDetector> detector = master.get()->createDetector(); mesos::internal::slave::Flags slaveFlags = CreateSlaveFlags(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags); ASSERT_SOME(slave); // Advance the clock to trigger agent registration. Clock::advance(slaveFlags.registration_backoff_factor); // Wait for the agent to register and get the agent ID. AWAIT_READY(slaveRegisteredMessage); const AgentID agentId = evolve(slaveRegisteredMessage->slave_id()); ContentType contentType = GetParam(); { master::Call call; call.set_type(master::Call::MARK_AGENT_GONE); call.mutable_mark_agent_gone()->mutable_agent_id()->CopyFrom(agentId); Future<process::http::Response> response = process::http::post( master.get()->pid, "api/v1", createBasicAuthHeaders(DEFAULT_CREDENTIAL), serialize(contentType, call), stringify(contentType)); AWAIT_EXPECT_RESPONSE_STATUS_EQ(process::http::OK().status, response); } auto scheduler = std::make_shared<MockHTTPScheduler>(); EXPECT_CALL(*scheduler, connected(_)) .WillOnce(scheduler::SendSubscribe(DEFAULT_FRAMEWORK_INFO)); Future<scheduler::Event::Subscribed> subscribed; EXPECT_CALL(*scheduler, subscribed(_, _)) .WillOnce(FutureArg<1>(&subscribed)); // Ignore heartbeats. EXPECT_CALL(*scheduler, heartbeat(_)) .WillRepeatedly(Return()); // Decline all offers. EXPECT_CALL(*scheduler, offers(_, _)) .WillRepeatedly(scheduler::DeclineOffers()); scheduler::TestMesos mesos(master.get()->pid, contentType, scheduler); AWAIT_READY(subscribed); FrameworkID frameworkId(subscribed->framework_id()); OperationID operationId; operationId.set_value("operation"); scheduler::Call::ReconcileOperations::Operation operation; operation.mutable_operation_id()->CopyFrom(operationId); operation.mutable_agent_id()->CopyFrom(agentId); const Future<scheduler::APIResult> result = mesos.call({createCallReconcileOperations(frameworkId, {operation})}); AWAIT_READY(result); // The master should respond with '200 OK' and with a `scheduler::Response`. ASSERT_EQ(process::http::Status::OK, result->status_code()); ASSERT_TRUE(result->has_response()); const scheduler::Response response = result->response(); ASSERT_EQ(scheduler::Response::RECONCILE_OPERATIONS, response.type()); ASSERT_TRUE(response.has_reconcile_operations()); const scheduler::Response::ReconcileOperations& reconcile = response.reconcile_operations(); ASSERT_EQ(1, reconcile.operation_statuses_size()); const OperationStatus& operationStatus = reconcile.operation_statuses(0); EXPECT_EQ(operationId, operationStatus.operation_id()); EXPECT_EQ(OPERATION_GONE_BY_OPERATOR, operationStatus.state()); EXPECT_FALSE(operationStatus.has_uuid()); }