// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string>
#include <vector>

#include <mesos/http.hpp>
#include <mesos/roles.hpp>

#include <process/clock.hpp>
#include <process/future.hpp>
#include <process/gtest.hpp>
#include <process/http.hpp>
#include <process/owned.hpp>
#include <process/pid.hpp>

#include <stout/none.hpp>
#include <stout/nothing.hpp>

#include "tests/containerizer.hpp"
#include "tests/mesos.hpp"
#include "tests/resources_utils.hpp"

#include "tests/master/mock_master_api_subscriber.hpp"

using mesos::internal::master::Master;
using mesos::internal::slave::Slave;

using mesos::master::detector::MasterDetector;

using std::string;
using std::vector;

using google::protobuf::RepeatedPtrField;

using process::Clock;
using process::Failure;
using process::Future;
using process::Owned;
using process::PID;

using process::http::Accepted;
using process::http::Headers;
using process::http::OK;
using process::http::Response;
using process::http::Unauthorized;

using testing::AtMost;
using testing::DoAll;

namespace mesos {
namespace internal {
namespace tests {

class RoleTest : public MesosTest {};


// This test checks that a framework cannot register with a role that
// is not in the configured list.
TEST_F(RoleTest, BadRegister)
{
  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
  frameworkInfo.set_roles(0, "invalid");

  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.roles = "foo,bar";

  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
  ASSERT_SOME(master);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<Nothing> error;
  EXPECT_CALL(sched, error(&driver, _))
    .WillOnce(FutureSatisfy(&error));

  driver.start();

  // Scheduler should get error message from the master.
  AWAIT_READY(error);

  driver.stop();
  driver.join();
}


// This test checks that when using implicit roles, a framework can
// register with a new role, make a dynamic reservation, and create a
// persistent volume.
TEST_F(RoleTest, ImplicitRoleRegister)
{
  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.allocation_interval = Milliseconds(50);

  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
  ASSERT_SOME(master);

  slave::Flags slaveFlags = CreateSlaveFlags();
  slaveFlags.resources = "cpus:1;mem:512;disk:1024";

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), slaveFlags);
  ASSERT_SOME(slave);

  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
  frameworkInfo.set_roles(0, "new-role-name");

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);

  // We use the filter explicitly here so that the resources will not
  // be filtered for 5 seconds (the default).
  Filters filters;
  filters.set_refuse_seconds(0);

  Resources unreserved = Resources::parse("disk:1024").get();
  Resources dynamicallyReserved =
    unreserved.pushReservation(createDynamicReservationInfo(
        frameworkInfo.roles(0), frameworkInfo.principal()));

  // We use this to capture offers from `resourceOffers`.
  Future<vector<Offer>> offers;

  EXPECT_CALL(sched, registered(&driver, _, _));

  // The expectation for the first offer.
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));

  driver.start();

  // In the first offer, expect an offer with unreserved resources.
  AWAIT_READY(offers);

  ASSERT_EQ(1u, offers->size());
  Offer offer = offers.get()[0];

  EXPECT_TRUE(Resources(offer.resources()).contains(
      allocatedResources(unreserved, frameworkInfo.roles(0))));
  EXPECT_FALSE(Resources(offer.resources()).contains(
      allocatedResources(dynamicallyReserved, frameworkInfo.roles(0))));

  // The expectation for the next offer.
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));

  // Reserve the resources.
  driver.acceptOffers({offer.id()}, {RESERVE(dynamicallyReserved)}, filters);

  // In the next offer, expect an offer with reserved resources.
  AWAIT_READY(offers);

  ASSERT_EQ(1u, offers->size());
  offer = offers.get()[0];

  EXPECT_TRUE(Resources(offer.resources()).contains(
      allocatedResources(dynamicallyReserved, frameworkInfo.roles(0))));
  EXPECT_FALSE(Resources(offer.resources()).contains(
      allocatedResources(unreserved, frameworkInfo.roles(0))));

  Resources volume = createPersistentVolume(
      Megabytes(64),
      frameworkInfo.roles(0),
      "id1",
      "path1",
      frameworkInfo.principal(),
      None(),
      frameworkInfo.principal());

  // The expectation for the next offer.
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));

  driver.acceptOffers({offer.id()}, {CREATE(volume)}, filters);

  // In the next offer, expect an offer with a persistent volume.
  AWAIT_READY(offers);

  ASSERT_EQ(1u, offers->size());
  offer = offers.get()[0];

  EXPECT_TRUE(Resources(offer.resources()).contains(
      allocatedResources(volume, frameworkInfo.roles(0))));
  EXPECT_FALSE(Resources(offer.resources()).contains(
      allocatedResources(dynamicallyReserved, frameworkInfo.roles(0))));
  EXPECT_FALSE(Resources(offer.resources()).contains(
      allocatedResources(unreserved, frameworkInfo.roles(0))));

  driver.stop();
  driver.join();
}


// This test checks that when using implicit roles, a static
// reservation for a new role can be made and used to launch a task.
TEST_F(RoleTest, ImplicitRoleStaticReservation)
{
  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.allocation_interval = Milliseconds(50);

  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
  ASSERT_SOME(master);

  MockExecutor exec(DEFAULT_EXECUTOR_ID);
  TestContainerizer containerizer(&exec);

  slave::Flags slaveFlags = CreateSlaveFlags();
  slaveFlags.resources = "cpus(role):1;mem(role):512";

  Owned<MasterDetector> detector = master.get()->createDetector();

  Try<Owned<cluster::Slave>> slave =
    StartSlave(detector.get(), &containerizer, slaveFlags);
  ASSERT_SOME(slave);

  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
  frameworkInfo.set_roles(0, "role");

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);

  // We use the filter explicitly here so that the resources will not
  // be filtered for 5 seconds (the default).
  Filters filters;
  filters.set_refuse_seconds(0);

  Resources staticallyReserved =
    Resources::parse(slaveFlags.resources.get()).get();

  // We use this to capture offers from `resourceOffers`.
  Future<vector<Offer>> offers;

  EXPECT_CALL(sched, registered(&driver, _, _));

  // The expectation for the first offer.
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers));

  driver.start();

  AWAIT_READY(offers);

  ASSERT_EQ(1u, offers->size());
  Offer offer = offers.get()[0];

  EXPECT_TRUE(Resources(offer.resources()).contains(
      allocatedResources(staticallyReserved, frameworkInfo.roles(0))));

  // Create a task to launch with the resources of `staticallyReserved`.
  TaskInfo taskInfo =
    createTask(offer.slave_id(), staticallyReserved, "exit 1", exec.id);

  EXPECT_CALL(exec, registered(_, _, _, _));

  Future<TaskInfo> launchTask;

  EXPECT_CALL(exec, launchTask(_, _))
    .WillOnce(FutureArg<1>(&launchTask));

  driver.acceptOffers({offer.id()}, {LAUNCH({taskInfo})}, filters);

  AWAIT_READY(launchTask);

  EXPECT_CALL(exec, shutdown(_))
    .Times(AtMost(1));

  driver.stop();
  driver.join();
}


// This test checks that the "/roles" endpoint returns the expected
// information when there are no known roles.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, EndpointEmpty)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  Future<Response> response = process::http::get(
      master.get()->pid,
      "roles",
      None(),
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

  AWAIT_EXPECT_RESPONSE_HEADER_EQ(APPLICATION_JSON, "Content-Type", response);

  Try<JSON::Value> parse = JSON::parse(response->body);
  ASSERT_SOME(parse);

  Try<JSON::Value> expected = JSON::parse(
      "{"
      "  \"roles\": []"
      "}");

  ASSERT_SOME(expected);

  EXPECT_EQ(*expected, *parse)
    << "expected " << stringify(*expected)
    << " vs actual " << stringify(*parse);
}


// This test checks that the "/roles" endpoint returns the expected
// information when the role whitelist is used but no frameworks
// are present.
TEST_F(RoleTest, EndpointWithWhitelistNoFrameworks)
{
  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.roles = "role1,role2";
  masterFlags.weights = "role1=5";

  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
  ASSERT_SOME(master);

  Future<Response> response = process::http::get(
      master.get()->pid,
      "roles",
      None(),
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

  AWAIT_EXPECT_RESPONSE_HEADER_EQ(APPLICATION_JSON, "Content-Type", response);

  Try<JSON::Value> parse = JSON::parse(response->body);
  ASSERT_SOME(parse);

  Try<JSON::Value> expected = JSON::parse(
      "{"
      "  \"roles\": ["
      "    {"
      "      \"frameworks\": [],"
      "      \"name\": \"*\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"*\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 1.0"
      "    },"
      "    {"
      "      \"frameworks\": [],"
      "      \"name\": \"role1\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"role1\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 5.0"
      "    },"
      "    {"
      "      \"frameworks\": [],"
      "      \"name\": \"role2\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"role2\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 1.0"
      "    }"
      "  ]"
      "}");

  ASSERT_SOME(expected);

  EXPECT_EQ(*expected, *parse)
    << "expected " << stringify(*expected)
    << " vs actual " << stringify(*parse);
}


// This test ensures that quota information is included
// in /roles endpoint of master.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, RolesEndpointContainsQuota)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  Resources quotaResources = Resources::parse("cpus:1;mem:512").get();

  mesos::quota::QuotaRequest request;
  request.set_role("foo");
  request.mutable_guarantee()->CopyFrom(quotaResources);

  // Use the force flag for setting quota that cannot be satisfied in
  // this empty cluster without any agents.
  request.set_force(true);

  {
    Future<Response> response = process::http::post(
        master.get()->pid,
        "quota",
        createBasicAuthHeaders(DEFAULT_CREDENTIAL),
        stringify(JSON::protobuf(request)));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
  }

  // Query the master roles endpoint and check it contains quota.
  {
    Future<Response> response = process::http::get(
        master.get()->pid,
        "roles",
        None(),
        createBasicAuthHeaders(DEFAULT_CREDENTIAL));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

    Try<JSON::Object> parse = JSON::parse<JSON::Object>(response->body);
    ASSERT_SOME(parse);

    Result<JSON::Array> roles = parse->find<JSON::Array>("roles");
    ASSERT_SOME(roles);
    EXPECT_EQ(1u, roles->values.size());

    JSON::Value role = roles->values[0].as<JSON::Value>();

    Try<JSON::Value> expected = JSON::parse(
        "{"
          "\"quota\":"
            "{"
              "\"role\":\"foo\","
              "\"consumed\": {},"
              "\"guarantee\":"
                "{"
                  "\"cpus\":1.0,"
                  "\"mem\":512.0"
                "},"
              "\"limit\":"
                "{"
                  "\"cpus\":1.0,"
                  "\"mem\":512.0"
                "}"
            "}"
        "}"
    );
    ASSERT_SOME(expected);

    EXPECT_TRUE(role.contains(*expected))
      << "expected " << stringify(*expected)
      << " vs actual " << stringify(role);
  }
}


// This test ensures that quota consumption is included
// in /roles endpoint of master.
//
// We set up the following that should be included in
// the quota consumption:
//   - Allocated unreserved resources
//   - Allocated reservation
//   - Unallocated reservation
//
// And we set up the following that should not be included
// in the quota consumption:
//   - Outstanding offer
//
// TODO(bmahler): Test hierarchical accounting accuracy.
//
// TODO(asekretenko): This test is disabled on Windows because it needs "posix"
// isolator to test quota consumption with multiple agents. After we have a
// simple way to obtain such setup regardless of the platform, this test should
// be re-enabled on Windows.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, RolesEndpointContainsConsumedQuota)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  // Start an agent with reserved resources and
  // allocate them to a task.
  slave::Flags agentFlags1 = CreateSlaveFlags();
  agentFlags1.resources = "cpus(role):1;mem(role):10;"
                          "disk:0;ports:[]";

  // We need to use the posix launcher to avoid agents
  // seeing each other's containers as orphans and
  // killing them.
  agentFlags1.launcher = "posix";

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave1 = StartSlave(detector.get(), agentFlags1);
  ASSERT_SOME(slave1);

  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
  frameworkInfo.set_roles(0, "role");

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  ExecutorInfo executorInfo = createExecutorInfo("dummy", "sleep 3600");

  Future<Nothing> task1Launched;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(DoAll(LaunchTasks(executorInfo, 1, 1, 10, "role"),
                    FutureSatisfy(&task1Launched)));

  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillRepeatedly(Return());

  driver.start();

  AWAIT_READY(task1Launched);

  // Now we have:
  //  - Allocated reservation: cpus:1;mem:10

  // Start an agent with unreserved resources and allocate
  // them to a task.

  Future<Nothing> task2Launched;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(DoAll(LaunchTasks(executorInfo, 1, 10, 100, "role"),
                    FutureSatisfy(&task2Launched)));

  slave::Flags agentFlags2 = CreateSlaveFlags();
  agentFlags2.resources = "cpus:10;mem:100;"
                          "disk:0;ports:[]";

  // We need to use the posix launcher to avoid agents
  // seeing each other's containers as orphans and
  // killing them.
  agentFlags2.launcher = "posix";

  Try<Owned<cluster::Slave>> slave2 = StartSlave(detector.get(), agentFlags2);
  ASSERT_SOME(slave2);

  AWAIT_READY(task2Launched);

  // Now we have:
  //  - Allocated reservation: cpus:1;mem:10
  //  - Allocated unreserved resources: cpus:10;mem:100

  // Start an agent with both reserved and unreserved
  // resources, but let them remain offered.

  Future<Nothing> offer;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureSatisfy(&offer));

  slave::Flags agentFlags3 = CreateSlaveFlags();
  agentFlags3.resources = "cpus(role):100;mem(role):1000;ports(role):[100-199]"
                          ";cpus:1000;mem:10000;disk:0;ports:[1000-1999]";

  // We need to use the posix launcher to avoid agents
  // seeing each other's containers as orphans and
  // killing them.
  agentFlags3.launcher = "posix";

  Try<Owned<cluster::Slave>> slave3 = StartSlave(detector.get(), agentFlags3);
  ASSERT_SOME(slave3);

  AWAIT_READY(offer);

  // Now we have:
  //  - Allocated reservation: cpus:1;mem:10
  //  - Allocated unreserved resources: cpus:10;mem:100
  //  - Offered reservation: cpus:100;mem:1000;ports:100
  //  - Offered unreserved resources: cpus:1000;mem:10000;ports:1000

  // Check that the /roles endopint has the correct quota
  // consumption information.
  {
    Future<Response> response = process::http::get(
        master.get()->pid,
        "roles",
        None(),
        createBasicAuthHeaders(DEFAULT_CREDENTIAL));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

    Try<JSON::Value> parse = JSON::parse(response->body);
    ASSERT_SOME(parse);

    Try<JSON::Value> expected = JSON::parse(
        "{"
        "  \"roles\": ["
        "    {"
        "      \"frameworks\": [\"" + frameworkId->value() + "\"],"
        "      \"name\": \"role\","
        "      \"resources\": {"
        "        \"cpus\": 1111.0,"
        "        \"mem\":  11110.0,"
        "        \"ports\": 1100.0"
        "      },"
        "      \"allocated\": {"
        "        \"cpus\": 11.0,"
        "        \"mem\":  110.0"
        "      },"
        "      \"offered\": {"
        "        \"cpus\": 1100.0,"
        "        \"mem\":  11000.0,"
        "        \"ports\": 1100.0"
        "      },"
        "      \"reserved\": {"
        "        \"cpus\": 101.0,"
        "        \"mem\":  1010.0,"
        "        \"ports\": 100.0"
        "      },"
        "      \"quota\": {"
        "        \"consumed\": {"
        "          \"cpus\": 111.0,"
        "          \"mem\": 1110.0,"
        "          \"ports\": 100.0"
        "        },"
        "        \"guarantee\": {},"
        "        \"limit\": {},"
        "        \"role\": \"role\""
        "      },"
        "      \"weight\": 1.0"
        "    }"
        "  ]"
        "}");

    ASSERT_SOME(expected);

    EXPECT_EQ(*expected, *parse)
      << "expected " << stringify(*expected)
      << " vs actual " << stringify(*parse);
  }
}


// This test checks that when using implicit roles, the "/roles"
// endpoint shows roles that have a configured weight even if they
// have no registered frameworks.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, EndpointImplicitRolesWeights)
{
  master::Flags masterFlags = CreateMasterFlags();
  masterFlags.weights = "roleX=5,roleY=4";

  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
  ASSERT_SOME(master);

  FrameworkInfo frameworkInfo1 = DEFAULT_FRAMEWORK_INFO;
  frameworkInfo1.set_roles(0, "roleX");

  MockScheduler sched1;
  MesosSchedulerDriver driver1(
      &sched1, frameworkInfo1, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId1;
  EXPECT_CALL(sched1, registered(&driver1, _, _))
    .WillOnce(FutureArg<1>(&frameworkId1));

  driver1.start();

  FrameworkInfo frameworkInfo2 = DEFAULT_FRAMEWORK_INFO;
  frameworkInfo2.set_roles(0, "roleZ");

  MockScheduler sched2;
  MesosSchedulerDriver driver2(
      &sched2, frameworkInfo2, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId2;
  EXPECT_CALL(sched2, registered(&driver2, _, _))
    .WillOnce(FutureArg<1>(&frameworkId2));

  driver2.start();

  AWAIT_READY(frameworkId1);
  AWAIT_READY(frameworkId2);

  Future<Response> response = process::http::get(
      master.get()->pid,
      "roles",
      None(),
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

  AWAIT_EXPECT_RESPONSE_HEADER_EQ(APPLICATION_JSON, "Content-Type", response);

  Try<JSON::Value> parse = JSON::parse(response->body);
  ASSERT_SOME(parse);

  Try<JSON::Value> expected = JSON::parse(
      "{"
      "  \"roles\": ["
      "    {"
      "      \"frameworks\": [\"" + frameworkId1->value() + "\"],"
      "      \"name\": \"roleX\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"roleX\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 5.0"
      "    },"
      "    {"
      "      \"frameworks\": [],"
      "      \"name\": \"roleY\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"roleY\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 4.0"
      "    },"
      "    {"
      "      \"frameworks\": [\"" + frameworkId2->value() + "\"],"
      "      \"name\": \"roleZ\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"roleZ\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 1.0"
      "    }"
      "  ]"
      "}");

  ASSERT_SOME(expected);

  EXPECT_EQ(*expected, *parse)
    << "expected " << stringify(*expected)
    << " vs actual " << stringify(*parse);

  driver1.stop();
  driver1.join();

  driver2.stop();
  driver2.join();
}


// This test checks that when using implicit roles, the "/roles"
// endpoint shows roles that have a configured quota even if they have
// no registered frameworks.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, EndpointImplicitRolesQuotas)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  Resources quotaResources = Resources::parse("cpus:1;mem:512").get();
  const RepeatedPtrField<Resource>& jsonQuotaResources =
    static_cast<const RepeatedPtrField<Resource>&>(quotaResources);

  // Send a quota request for a new role name. Note that we set
  // "force" to true because we're setting a quota that can't
  // currently be satisfied by the resources in the cluster (because
  // there are no slaves registered).
  string quotaRequestBody = strings::format(
      "{\"role\":\"non-existent-role\",\"guarantee\":%s,\"force\":true}",
      JSON::protobuf(jsonQuotaResources)).get();

  Future<Response> quotaResponse = process::http::post(
      master.get()->pid,
      "quota",
      createBasicAuthHeaders(DEFAULT_CREDENTIAL),
      quotaRequestBody);

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, quotaResponse)
    << quotaResponse->body;

  Future<Response> rolesResponse = process::http::get(
      master.get()->pid,
      "roles",
      None(),
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, rolesResponse)
    << rolesResponse->body;

  AWAIT_EXPECT_RESPONSE_HEADER_EQ(
      APPLICATION_JSON, "Content-Type", rolesResponse);

  Try<JSON::Value> parse = JSON::parse(rolesResponse->body);
  ASSERT_SOME(parse);

  Try<JSON::Value> expected = JSON::parse(
      "{"
      "  \"roles\": ["
      "    {"
      "      \"frameworks\": [],"
      "      \"name\": \"non-existent-role\","
      "      \"resources\": {},"
      "      \"allocated\": {},"
      "      \"offered\": {},"
      "      \"reserved\": {},"
      "      \"quota\": {"
      "        \"role\": \"non-existent-role\","
      "        \"consumed\": {},"
      "        \"guarantee\": {},"
      "        \"limit\": {}"
      "      },"
      "      \"weight\": 1.0"
      "    }"
      "  ]"
      "}");

  ASSERT_SOME(expected);
  EXPECT_TRUE(parse->contains(expected.get()));

  // Remove the quota, and check that the role no longer appears in
  // the "/roles" endpoint.
  Future<Response> deleteResponse = process::http::requestDelete(
      master.get()->pid,
      "quota/non-existent-role",
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, deleteResponse)
    << deleteResponse->body;

  rolesResponse = process::http::get(
      master.get()->pid,
      "roles",
      None(),
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, rolesResponse)
    << rolesResponse->body;

  AWAIT_EXPECT_RESPONSE_HEADER_EQ(
      APPLICATION_JSON, "Content-Type", rolesResponse);

  parse = JSON::parse(rolesResponse->body);
  ASSERT_SOME(parse);

  expected = JSON::parse(
      "{"
      "  \"roles\": []"
      "}");

  ASSERT_SOME(expected);

  EXPECT_EQ(*expected, *parse)
    << "expected " << stringify(*expected)
    << " vs actual " << stringify(*parse);
}


// This test ensures that roles with only reservations are
// included in the /roles endpoint.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, EndpointImplicitRolesReservations)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  v1::MockMasterAPISubscriber subscriber;

  AWAIT_READY(subscriber.subscribe(master.get()->pid));

  Future<Nothing> agentAdded;
  EXPECT_CALL(subscriber, agentAdded(_))
    .WillOnce(FutureSatisfy(&agentAdded));

  Owned<MasterDetector> detector = master.get()->createDetector();

  slave::Flags agentFlags = CreateSlaveFlags();
  agentFlags.resources = "cpus(role):1;mem(role):10";

  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), agentFlags);

  AWAIT_READY(agentAdded);

  // Check that the /roles endpoint contains the role.
  {
    Future<Response> response = process::http::get(
        master.get()->pid,
        "roles",
        None(),
        createBasicAuthHeaders(DEFAULT_CREDENTIAL));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

    Try<JSON::Value> parse = JSON::parse(response->body);
    ASSERT_SOME(parse);

    Try<JSON::Value> expected = JSON::parse(
        "{"
        "  \"roles\": ["
        "    {"
        "      \"frameworks\": [],"
        "      \"name\": \"role\","
        "      \"resources\": {},"
        "      \"allocated\": {},"
        "      \"offered\": {},"
        "      \"reserved\": {"
        "        \"cpus\": 1.0,"
        "        \"mem\":  10.0"
        "      },"
        "      \"quota\": {"
        "        \"consumed\": {"
        "          \"cpus\": 1.0,"
        "          \"mem\": 10.0"
        "        },"
        "        \"guarantee\": {},"
        "        \"limit\": {},"
        "        \"role\": \"role\""
        "      },"
        "      \"weight\": 1.0"
        "    }"
        "  ]"
        "}");

    ASSERT_SOME(expected);

    EXPECT_EQ(*expected, *parse)
      << "expected " << stringify(*expected)
      << " vs actual " << stringify(*parse);
  }
}


// This test ensures that ancestor roles are exposed when
// there are no direct objects associated with them.
//
// TODO(bmahler): This currently only tests the reservation
// case, but we should also test the allocation, framework
// subsription, and quota/weight configuration cases.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, EndpointImplicitRolesAncestors)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  v1::MockMasterAPISubscriber subscriber;

  AWAIT_READY(subscriber.subscribe(master.get()->pid));

  Future<Nothing> agentAdded;
  EXPECT_CALL(subscriber, agentAdded(_))
    .WillOnce(FutureSatisfy(&agentAdded));

  Owned<MasterDetector> detector = master.get()->createDetector();

  slave::Flags agentFlags = CreateSlaveFlags();
  agentFlags.resources = "cpus(ancestor/child):1;mem(ancestor/child):10;";

  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), agentFlags);

  AWAIT_READY(agentAdded);

  // Check that the /roles endpoint contains the role and
  // its ancestor.
  {
    Future<Response> response = process::http::get(
        master.get()->pid,
        "roles",
        None(),
        createBasicAuthHeaders(DEFAULT_CREDENTIAL));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

    Try<JSON::Value> parse = JSON::parse(response->body);
    ASSERT_SOME(parse);

    Try<JSON::Value> expected = JSON::parse(
        "{"
        "  \"roles\": ["
        "    {"
        "      \"frameworks\": [],"
        "      \"name\": \"ancestor\","
        "      \"resources\": {},"
        "      \"allocated\": {},"
        "      \"offered\": {},"
        "      \"reserved\": {"
        "        \"cpus\": 1.0,"
        "        \"mem\":  10.0"
        "      },"
        "      \"quota\": {"
        "        \"consumed\": {"
        "          \"cpus\": 1.0,"
        "          \"mem\": 10.0"
        "        },"
        "        \"guarantee\": {},"
        "        \"limit\": {},"
        "        \"role\": \"ancestor\""
        "      },"
        "      \"weight\": 1.0"
        "    },"
        "    {"
        "      \"frameworks\": [],"
        "      \"name\": \"ancestor/child\","
        "      \"resources\": {},"
        "      \"allocated\": {},"
        "      \"offered\": {},"
        "      \"reserved\": {"
        "        \"cpus\": 1.0,"
        "        \"mem\":  10.0"
        "      },"
        "      \"quota\": {"
        "        \"consumed\": {"
        "          \"cpus\": 1.0,"
        "          \"mem\": 10.0"
        "        },"
        "        \"guarantee\": {},"
        "        \"limit\": {},"
        "        \"role\": \"ancestor/child\""
        "      },"
        "      \"weight\": 1.0"
        "    }"
        "  ]"
        "}");

    ASSERT_SOME(expected);

    EXPECT_EQ(*expected, *parse)
      << "expected " << stringify(*expected)
      << " vs actual " << stringify(*parse);
  }
}


// This test ensures that master adds/removes all roles of
// a multi-role framework when it registers/terminates.
TEST_F_TEMP_DISABLED_ON_WINDOWS(
    RoleTest,
    AddAndRemoveFrameworkWithMultipleRoles)
{
  // When we test removeFramework later in this test, we have to
  // be sure the teardown call is processed completely before
  // sending request to `getRoles` API.
  Clock::pause();

  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  FrameworkInfo framework = DEFAULT_FRAMEWORK_INFO;
  framework.set_roles(0, "role1");
  framework.add_roles("role2");

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, framework, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));;

  driver.start();

  AWAIT_READY(frameworkId);

  // Tests all roles of the multi-role framework are added.
  {
    Future<Response> response = process::http::get(
        master.get()->pid,
        "roles",
        None(),
        createBasicAuthHeaders(DEFAULT_CREDENTIAL));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

    Try<JSON::Value> parse = JSON::parse(response->body);
    ASSERT_SOME(parse);

    Try<JSON::Value> expected = JSON::parse(
        "{"
        "  \"roles\": ["
        "    {"
        "      \"frameworks\": [\"" + frameworkId->value() + "\"],"
        "      \"name\": \"role1\","
        "      \"resources\": {},"
        "      \"allocated\": {},"
        "      \"offered\": {},"
        "      \"reserved\": {},"
        "      \"quota\": {"
        "        \"role\": \"role1\","
        "        \"consumed\": {},"
        "        \"guarantee\": {},"
        "        \"limit\": {}"
        "      },"
        "      \"weight\": 1.0"
        "    },"
        "    {"
        "      \"frameworks\": [\"" + frameworkId->value() + "\"],"
        "      \"name\": \"role2\","
        "      \"resources\": {},"
        "      \"allocated\": {},"
        "      \"offered\": {},"
        "      \"reserved\": {},"
        "      \"quota\": {"
        "        \"role\": \"role2\","
        "        \"consumed\": {},"
        "        \"guarantee\": {},"
        "        \"limit\": {}"
        "      },"
        "      \"weight\": 1.0"
        "    }"
        "  ]"
        "}");

    ASSERT_SOME(expected);

    EXPECT_EQ(*expected, *parse)
      << "expected " << stringify(*expected)
      << " vs actual " << stringify(*parse);
  }

  // Set expectation that Master receives teardown call.
  Future<mesos::scheduler::Call> teardownCall = FUTURE_CALL(
      mesos::scheduler::Call(), mesos::scheduler::Call::TEARDOWN, _, _);

  driver.stop();
  driver.join();

  // Wait for teardown call to be dispatched.
  AWAIT_READY(teardownCall);

  // Make sure the teardown call is processed completely.
  Clock::settle();

  // Tests all roles of multi-role framework are removed.
  {
    Future<Response> response = process::http::get(
        master.get()->pid,
        "roles",
        None(),
        createBasicAuthHeaders(DEFAULT_CREDENTIAL));

    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);

    Try<JSON::Value> parse = JSON::parse(response->body);
    ASSERT_SOME(parse);

    Try<JSON::Value> expected = JSON::parse(
        "{"
        "  \"roles\": []"
        "}");

    ASSERT_SOME(expected);

    EXPECT_EQ(*expected, *parse)
      << "expected " << stringify(*expected)
      << " vs actual " << stringify(*parse);  }
}


// This tests the parse function of roles.
TEST_F(RoleTest, Parsing)
{
  vector<string> v = {"abc", "edf", "hgi"};

  Try<vector<string>> r1 = roles::parse("abc,edf,hgi");
  EXPECT_SOME_EQ(v, r1);

  Try<vector<string>> r2 = roles::parse("abc,edf,hgi,");
  EXPECT_SOME_EQ(v, r2);

  Try<vector<string>> r3 = roles::parse(",abc,edf,hgi");
  EXPECT_SOME_EQ(v, r3);

  Try<vector<string>> r4 = roles::parse("abc,,edf,hgi");
  EXPECT_SOME_EQ(v, r4);

  EXPECT_ERROR(roles::parse("foo,.,*"));
}


TEST_F(RoleTest, Ancestors)
{
  EXPECT_EQ(vector<string>(),
            roles::ancestors("role"));

  EXPECT_EQ(vector<string>({"a/b/c", "a/b", "a"}),
            roles::ancestors("a/b/c/d"));
}


// This tests the validate functions of roles. Keep in mind that
// roles::validate returns Option<Error>, so it will return None() when
// validation succeeds, or Error() when validation fails.
TEST_F(RoleTest, Validate)
{
  EXPECT_NONE(roles::validate("foo"));
  EXPECT_NONE(roles::validate("123"));
  EXPECT_NONE(roles::validate("foo_123"));
  EXPECT_NONE(roles::validate("*"));
  EXPECT_NONE(roles::validate("foo-bar"));
  EXPECT_NONE(roles::validate("foo.bar"));
  EXPECT_NONE(roles::validate("foo..bar"));
  EXPECT_NONE(roles::validate("..."));
  EXPECT_NONE(roles::validate("foo/bar"));
  EXPECT_NONE(roles::validate("foo/.bar"));
  EXPECT_NONE(roles::validate("foo/bar/baz"));
  EXPECT_NONE(roles::validate("a/b/c/d/e/f/g/h"));

  EXPECT_SOME(roles::validate(""));
  EXPECT_SOME(roles::validate("."));
  EXPECT_SOME(roles::validate(".."));
  EXPECT_SOME(roles::validate("-foo"));
  EXPECT_SOME(roles::validate("/"));
  EXPECT_SOME(roles::validate("/foo"));
  EXPECT_SOME(roles::validate("foo/"));
  EXPECT_SOME(roles::validate("foo//bar"));
  EXPECT_SOME(roles::validate("foo/bar/"));
  EXPECT_SOME(roles::validate("foo bar"));
  EXPECT_SOME(roles::validate("foo\tbar"));
  EXPECT_SOME(roles::validate("foo\nbar"));

  EXPECT_SOME(roles::validate("./."));
  EXPECT_SOME(roles::validate("../.."));
  EXPECT_SOME(roles::validate("./foo"));
  EXPECT_SOME(roles::validate("../foo"));
  EXPECT_SOME(roles::validate("foo/."));
  EXPECT_SOME(roles::validate("foo/.."));
  EXPECT_SOME(roles::validate("foo/./bar"));
  EXPECT_SOME(roles::validate("foo/../bar"));
  EXPECT_SOME(roles::validate("foo/-bar"));
  EXPECT_SOME(roles::validate("foo/*"));
  EXPECT_SOME(roles::validate("foo/*/bar"));
  EXPECT_SOME(roles::validate("*/foo"));

  EXPECT_NONE(roles::validate({"foo", "bar", "*"}));

  EXPECT_SOME(roles::validate({"foo", ".", "*"}));
}


TEST_F(RoleTest, isStrictSubroleOf)
{
  EXPECT_TRUE(roles::isStrictSubroleOf("foo/bar", "foo"));
  EXPECT_TRUE(roles::isStrictSubroleOf("foo/bar/baz", "foo"));
  EXPECT_FALSE(roles::isStrictSubroleOf("foo", "foo"));
  EXPECT_FALSE(roles::isStrictSubroleOf("bar", "foo"));
  EXPECT_FALSE(roles::isStrictSubroleOf("foobar", "foo"));
}


// Testing get without authentication and with bad credentials.
TEST_F(RoleTest, EndpointBadAuthentication)
{
  // Set up a master with authentication required.
  // Note that the default master test flags enable HTTP authentication.
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  // Get request without authentication.
  Future<Response> response = process::http::get(
      master.get()->pid,
      "roles");

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response);

  // Bad credentials which should fail authentication.
  Credential badCredential;
  badCredential.set_principal("badPrincipal");
  badCredential.set_secret("badSecret");

  // Get request with bad authentication.
  response = process::http::get(
    master.get()->pid,
    "roles",
    None(),
    createBasicAuthHeaders(badCredential));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response);
}


// This test confirms that our handling of persistent volumes from hierarchical
// roles does not cause leaking of volumes. Since hierarchical roles contain
// literal `/` an implementation not taking this into account could map the name
// of a hierarchical role `A/B` onto a directory hierarchy `A/B`. If the
// persistent volume with persistence id `ID` and role `ROLE` is mapped to a
// path `ROLE/ID`, it becomes impossible to distinguish the last component of a
// hierarchical role from a persistence id.
//
// This performs the following checks:
//
// 1) Run two tasks with volumes whose role and id overlap on the file system in
// the naive implementation. The tasks should not be able to see each others
// volumes.
//
// 2) Destroy the previously created volumes in an order such that the in the
// naive implementation less nested volume is destroyed first. This should not
// destroy the more nested volume (e.g., since it is not created as a
// subdirectory).
//
// TODO(bbannier): Figure out a way to run the test command on Windows.
TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, VolumesInOverlappingHierarchies)
{
  constexpr char PATH[] = "path";
  constexpr Bytes DISK_SIZE = Megabytes(1);

  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  // Capture the SlaveID so we can use it in create/destroy volumes API calls.
  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);
  const SlaveID slaveId = slaveRegisteredMessage->slave_id();

  // Helper function which starts a framework in a role and creates a
  // persistent volume with the given id. The framework creates a task
  // using the volume and makes sure that no volumes from other roles
  // are leaked into the volume.
  auto runTask = [&master, &PATH](
      const string& role, const string& id) {
    FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
    frameworkInfo.set_roles(0, role);

    MockScheduler sched;
    MesosSchedulerDriver driver(
        &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);

    EXPECT_CALL(sched, registered(&driver, _, _));

    Future<vector<Offer>> offers;
    EXPECT_CALL(sched, resourceOffers(&driver, _))
      .WillOnce(FutureArg<1>(&offers))
      .WillRepeatedly(Return()); // Ignore subsequent offers.

    driver.start();

    AWAIT_READY(offers);

    ASSERT_FALSE(offers->empty());

    // Create a reserved disk. We only create a small disk so
    // we have remaining disk to offer to other frameworks.
    Resource reservedDisk = createReservedResource(
        "disk",
        "1",
        createDynamicReservationInfo(role, DEFAULT_CREDENTIAL.principal()));

    // Create a persistent volume on the reserved disk.
    Resource volume = createPersistentVolume(
        reservedDisk,
        id,
        PATH,
        DEFAULT_CREDENTIAL.principal(),
        frameworkInfo.principal());

    // Create a task which uses the volume and checks that
    // it contains no files leaked from another role.
    const Offer& offer = offers.get()[0];

    Resources cpusMem =
      Resources(offer.resources()).filter([](const Resource& r) {
        return r.name() == "cpus" || r.name() == "mem";
      });

    Resources taskResources = cpusMem + volume;

    // Create a task confirming that the directory `path` is empty.
    // Note that we do not explicitly confirm that `path` exists here.
    TaskInfo task = createTask(
        offer.slave_id(),
        taskResources,
        "! (ls -Av path | grep -q .)");

    // We expect three status updates for the task.
    Future<TaskStatus> status0, status1, status2;
    EXPECT_CALL(sched, statusUpdate(&driver, _))
      .WillOnce(FutureArg<1>(&status0))
      .WillOnce(FutureArg<1>(&status1))
      .WillOnce(FutureArg<1>(&status2));

    // Accept the offer.
    driver.acceptOffers(
        {offer.id()},
        {RESERVE(reservedDisk), CREATE(volume), LAUNCH({task})});

    AWAIT_READY(status0);

    EXPECT_EQ(task.task_id(), status0->task_id());
    EXPECT_EQ(TASK_STARTING, status0->state());

    AWAIT_READY(status1);

    EXPECT_EQ(task.task_id(), status1->task_id());
    EXPECT_EQ(TASK_RUNNING, status1->state());

    AWAIT_READY(status2);

    EXPECT_EQ(task.task_id(), status2->task_id());
    EXPECT_EQ(TASK_FINISHED, status2->state())
      << "Task for role '" << role << "' and id '" << id << "' did not succeed";

    driver.stop();
    driver.join();
  };

  // Helper function to destroy a volume with given role and id.
  auto destroyVolume = [&slaveId, &master, &PATH, DISK_SIZE](
      const string& role, const string& id) {
    Resource volume = createPersistentVolume(
        DISK_SIZE,
        role,
        id,
        PATH,
        DEFAULT_CREDENTIAL.principal(),
        None(),
        DEFAULT_CREDENTIAL.principal());

    v1::master::Call destroyVolumesCall;
    destroyVolumesCall.set_type(v1::master::Call::DESTROY_VOLUMES);

    v1::master::Call::DestroyVolumes* destroyVolumes =
      destroyVolumesCall.mutable_destroy_volumes();
    destroyVolumes->add_volumes()->CopyFrom(evolve(volume));
    destroyVolumes->mutable_agent_id()->CopyFrom(evolve(slaveId));

    constexpr ContentType CONTENT_TYPE = ContentType::PROTOBUF;

    Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL);
    headers["Accept"] = stringify(CONTENT_TYPE);

    return process::http::post(
        master.get()->pid,
        "api/v1",
        headers,
        serialize(CONTENT_TYPE, destroyVolumesCall),
        stringify(CONTENT_TYPE));
  };

  // Run two tasks. In the naive storage scheme of volumes from hierarchical
  // role frameworks, the first volume would be created under paths
  // `a/b/c/d/id/` and the second one under `a/b/c/d/`. The second task would in
  // that case incorrectly see a directory `id` in its persistent volume.
  runTask("a/b/c/d", "id");
  runTask("a/b/c", "d");

  // Destroy both volumes. Even though the role `a/b/c` is a prefix of the role
  // `a/b/c/d`, destroying the former role's volume `d` should not interfere
  // with the latter's volume `id`.
  AWAIT_EXPECT_RESPONSE_STATUS_EQ(
      Accepted().status, destroyVolume("a/b/c", "d"));

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(
      Accepted().status, destroyVolume("a/b/c/d", "id"));
}

}  // namespace tests {
}  // namespace internal {
}  // namespace mesos {
