This is an automated email from the ASF dual-hosted git repository. tillt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 3ed4cd51f0eea1f86b0a8a25c95f6005565e3010 Author: Till Toenshoff <[email protected]> AuthorDate: Tue Nov 20 14:45:38 2018 +0100 Added test reproducing crash on authorization failure. This test reproduces the scenario as described in MESOS-9317. The test attempts to create a persistent volume by a web request to the authorized V1 operator endpoint. The test assures that the underlying authorization request fails as it can in production due to failures in the authorization backend. Without fixing MESOS-9317, this test crashes the master process as the code-path involved will attempt to access the contents of the awaited future even though the future had failed. Review: https://reviews.apache.org/r/69368/ --- src/tests/master_tests.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp index ac6bf37..8ed1e89 100644 --- a/src/tests/master_tests.cpp +++ b/src/tests/master_tests.cpp @@ -106,6 +106,7 @@ using process::PID; using process::Promise; using process::http::Accepted; +using process::http::InternalServerError; using process::http::OK; using process::http::Response; using process::http::Unauthorized; @@ -10087,6 +10088,70 @@ TEST_P(MasterTestPrePostReservationRefinement, CreateAndDestroyVolumesV1) AWAIT_EXPECT_RESPONSE_STATUS_EQ(Accepted().status, v1DestroyVolumesResponse); } + +// This test validates that an authorization error when requesting +// volume creation does result in an internal server error. +// See MESOS-9317. +TEST_F(MasterTest, CreateVolumesV1AuthorizationFailure) +{ + MockAuthorizer authorizer; + Try<Owned<cluster::Master>> master = StartMaster(&authorizer); + ASSERT_SOME(master); + + // For capturing the `SlaveID` so we can use it in the create/destroy + // volumes API call. + Future<SlaveRegisteredMessage> slaveRegisteredMessage = + FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _); + + Owned<MasterDetector> detector = master.get()->createDetector(); + + slave::Flags slaveFlags = CreateSlaveFlags(); + // Do static reservation so we can create persistent volumes from it. + slaveFlags.resources = "disk(role1):1024"; + + Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags); + + ASSERT_SOME(slave); + + AWAIT_READY(slaveRegisteredMessage); + SlaveID slaveId = slaveRegisteredMessage->slave_id(); + + // Create the persistent volume. + v1::master::Call v1CreateVolumesCall; + v1CreateVolumesCall.set_type(v1::master::Call::CREATE_VOLUMES); + v1::master::Call_CreateVolumes* createVolumes = + v1CreateVolumesCall.mutable_create_volumes(); + + Resources volume = createPersistentVolume( + Megabytes(64), + "role1", + "id1", + "path1", + None(), + None(), + DEFAULT_CREDENTIAL.principal()); + + createVolumes->mutable_agent_id()->CopyFrom(evolve(slaveId)); + createVolumes->mutable_volumes()->CopyFrom(v1::Resources(evolve(volume))); + + ContentType contentType = ContentType::PROTOBUF; + + Promise<bool> promise; + EXPECT_CALL(authorizer, authorized(_)) + .WillOnce(Return(promise.future())); + + Future<Response> response = process::http::post( + master.get()->pid, + "api/v1", + createBasicAuthHeaders(DEFAULT_CREDENTIAL), + serialize(contentType, v1CreateVolumesCall), + stringify(contentType)); + + promise.fail("Authorizer failure"); + + AWAIT_EXPECT_RESPONSE_STATUS_EQ(InternalServerError().status, response); +} + } // namespace tests { } // namespace internal { } // namespace mesos {
