blob: 0516ab573d9f4f2af249978e15ebf52c2afb5359 [file] [log] [blame]
/**
* 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 <stdarg.h>
#include <stdint.h>
#include <gmock/gmock.h>
#include "master/drf_sorter.hpp"
#include "master/sorter.hpp"
using namespace mesos;
using mesos::internal::master::allocator::Sorter;
using mesos::internal::master::allocator::DRFSorter;
using std::list;
using std::string;
void checkSorter(Sorter& sorter, uint32_t count, ...)
{
va_list args;
va_start(args, count);
list<string> ordering = sorter.sort();
EXPECT_EQ(ordering.size(), count);
foreach (const string& actual, ordering) {
const char* expected = va_arg(args, char*);
EXPECT_EQ(actual, expected);
}
va_end(args);
}
TEST(SorterTest, DRFSorter)
{
DRFSorter sorter;
Resources totalResources = Resources::parse("cpus:100;mem:100").get();
sorter.add(totalResources);
sorter.add("a");
Resources aResources = Resources::parse("cpus:5;mem:5").get();
sorter.allocated("a", aResources);
Resources bResources = Resources::parse("cpus:6;mem:6").get();
sorter.add("b");
sorter.allocated("b", bResources);
// shares: a = .05, b = .06
checkSorter(sorter, 2, "a", "b");
Resources cResources = Resources::parse("cpus:1;mem:1").get();
sorter.add("c");
sorter.allocated("c", cResources);
Resources dResources = Resources::parse("cpus:3;mem:1").get();
sorter.add("d");
sorter.allocated("d", dResources);
// shares: a = .05, b = .06, c = .01, d = .03
checkSorter(sorter, 4, "c", "d", "a", "b");
sorter.remove("a");
Resources bUnallocated = Resources::parse("cpus:4;mem:4").get();
sorter.unallocated("b", bUnallocated);
// shares: b = .02, c = .01, d = .03
checkSorter(sorter, 3, "c", "b", "d");
Resources eResources = Resources::parse("cpus:1;mem:5").get();
sorter.add("e");
sorter.allocated("e", eResources);
Resources removedResources = Resources::parse("cpus:50;mem:0").get();
sorter.remove(removedResources);
// total resources is now cpus = 50, mem = 100
// shares: b = .04, c = .02, d = .06, e = .05
checkSorter(sorter, 4, "c", "b", "e", "d");
Resources addedResources = Resources::parse("cpus:0;mem:100").get();
sorter.add(addedResources);
// total resources is now cpus = 50, mem = 200
Resources fResources = Resources::parse("cpus:5;mem:1").get();
sorter.add("f");
sorter.allocated("f", fResources);
Resources cResources2 = Resources::parse("cpus:0;mem:15").get();
sorter.allocated("c", cResources2);
// shares: b = .04, c = .08, d = .06, e = .025, f = .1
checkSorter(sorter, 5, "e", "b", "d", "c", "f");
EXPECT_TRUE(sorter.contains("b"));
EXPECT_FALSE(sorter.contains("a"));
EXPECT_EQ(sorter.count(), 5);
sorter.deactivate("d");
EXPECT_TRUE(sorter.contains("d"));
checkSorter(sorter, 4, "e", "b", "c", "f");
EXPECT_EQ(sorter.count(), 5);
sorter.activate("d");
checkSorter(sorter, 5, "e", "b", "d", "c", "f");
}
TEST(SorterTest, WDRFSorter)
{
DRFSorter sorter;
sorter.add(Resources::parse("cpus:100;mem:100").get());
sorter.add("a");
sorter.allocated("a", Resources::parse("cpus:5;mem:5").get());
sorter.add("b", 2);
sorter.allocated("b", Resources::parse("cpus:6;mem:6").get());
// shares: a = .05, b = .03
checkSorter(sorter, 2, "b", "a");
sorter.add("c");
sorter.allocated("c", Resources::parse("cpus:4;mem:4").get());
// shares: a = .05, b = .03, c = .04
checkSorter(sorter, 3, "b", "c", "a");
sorter.add("d", 10);
sorter.allocated("d", Resources::parse("cpus:10;mem:20").get());
// shares: a = .05, b = .03, c = .04, d = .02
checkSorter(sorter, 4, "d", "b", "c", "a");
sorter.remove("b");
checkSorter(sorter, 3, "d", "c", "a");
sorter.allocated("d", Resources::parse("cpus:10;mem:25").get());
// shares: a = .05, c = .04, d = .045
checkSorter(sorter, 3, "c", "d", "a");
sorter.add("e", .1);
sorter.allocated("e", Resources::parse("cpus:1;mem:1").get());
// shares: a = .05, c = .04, d = .045, e = .1
checkSorter(sorter, 4, "c", "d", "a", "e");
sorter.remove("a");
checkSorter(sorter, 3, "c", "d", "e");
}