|
@@ -0,0 +1,820 @@
|
|
|
|
+/**
|
|
|
|
+ * 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.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+package org.apache.hadoop.yarn.server.resourcemanager.reservation.planning;
|
|
|
|
+
|
|
|
|
+import static org.junit.Assert.assertTrue;
|
|
|
|
+import static org.junit.Assert.fail;
|
|
|
|
+import static org.mockito.Mockito.mock;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Random;
|
|
|
|
+
|
|
|
|
+import org.apache.hadoop.yarn.api.records.ReservationDefinition;
|
|
|
|
+import org.apache.hadoop.yarn.api.records.ReservationId;
|
|
|
|
+import org.apache.hadoop.yarn.api.records.ReservationRequest;
|
|
|
|
+import org.apache.hadoop.yarn.api.records.ReservationRequestInterpreter;
|
|
|
|
+import org.apache.hadoop.yarn.api.records.ReservationRequests;
|
|
|
|
+import org.apache.hadoop.yarn.api.records.Resource;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacityOverTimePolicy;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.InMemoryPlan;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.InMemoryReservationAllocation;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationAllocation;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationSchedulerConfiguration;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationSystemTestUtil;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningException;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.AlignedPlannerWithGreedy;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.ReservationAgent;
|
|
|
|
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics;
|
|
|
|
+import org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator;
|
|
|
|
+import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
|
|
|
+import org.apache.hadoop.yarn.util.resource.Resources;
|
|
|
|
+import org.junit.Before;
|
|
|
|
+import org.junit.Test;
|
|
|
|
+import org.mortbay.log.Log;
|
|
|
|
+
|
|
|
|
+public class TestAlignedPlanner {
|
|
|
|
+
|
|
|
|
+ ReservationAgent agent;
|
|
|
|
+ InMemoryPlan plan;
|
|
|
|
+ Resource minAlloc = Resource.newInstance(1024, 1);
|
|
|
|
+ ResourceCalculator res = new DefaultResourceCalculator();
|
|
|
|
+ Resource maxAlloc = Resource.newInstance(1024 * 8, 8);
|
|
|
|
+ Random rand = new Random();
|
|
|
|
+ long step;
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testSingleReservationAccept() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario1();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 5 * step, // Job arrival time
|
|
|
|
+ 20 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(2048, 2), // Capability
|
|
|
|
+ 10, // Num containers
|
|
|
|
+ 5, // Concurrency
|
|
|
|
+ 10 * step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ORDER, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was accepted
|
|
|
|
+ assertTrue("Agent-based allocation failed", reservationID != null);
|
|
|
|
+ assertTrue("Agent-based allocation failed", plan.getAllReservations()
|
|
|
|
+ .size() == numJobsInScenario + 1);
|
|
|
|
+
|
|
|
|
+ // Get reservation
|
|
|
|
+ ReservationAllocation alloc1 = plan.getReservationById(reservationID);
|
|
|
|
+
|
|
|
|
+ // Verify allocation
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 10 * step, 20 * step, 10, 2048, 2));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testOrderNoGapImpossible() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10L, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ORDER_NO_GAP, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ try {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+ fail();
|
|
|
|
+ } catch (PlanningException e) {
|
|
|
|
+ // Expected failure
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was not accepted
|
|
|
|
+ assertTrue("Agent-based allocation should have failed", plan
|
|
|
|
+ .getAllReservations().size() == numJobsInScenario);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testOrderNoGapImpossible2() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 13 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 10, // Num containers
|
|
|
|
+ 10, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ORDER_NO_GAP, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ try {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+ fail();
|
|
|
|
+ } catch (PlanningException e) {
|
|
|
|
+ // Expected failure
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was not accepted
|
|
|
|
+ assertTrue("Agent-based allocation should have failed", plan
|
|
|
|
+ .getAllReservations().size() == numJobsInScenario);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testOrderImpossible() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ 2 * step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ORDER, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ try {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+ fail();
|
|
|
|
+ } catch (PlanningException e) {
|
|
|
|
+ // Expected failure
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was not accepted
|
|
|
|
+ assertTrue("Agent-based allocation should have failed", plan
|
|
|
|
+ .getAllReservations().size() == numJobsInScenario);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testAnyImpossible() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ 3 * step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ 2 * step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ANY, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ try {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+ fail();
|
|
|
|
+ } catch (PlanningException e) {
|
|
|
|
+ // Expected failure
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was not accepted
|
|
|
|
+ assertTrue("Agent-based allocation should have failed", plan
|
|
|
|
+ .getAllReservations().size() == numJobsInScenario);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testAnyAccept() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ 2 * step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ANY, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was accepted
|
|
|
|
+ assertTrue("Agent-based allocation failed", reservationID != null);
|
|
|
|
+ assertTrue("Agent-based allocation failed", plan.getAllReservations()
|
|
|
|
+ .size() == numJobsInScenario + 1);
|
|
|
|
+
|
|
|
|
+ // Get reservation
|
|
|
|
+ ReservationAllocation alloc1 = plan.getReservationById(reservationID);
|
|
|
|
+
|
|
|
|
+ // Verify allocation
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 14 * step, 15 * step, 20, 1024, 1));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testAllAccept() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was accepted
|
|
|
|
+ assertTrue("Agent-based allocation failed", reservationID != null);
|
|
|
|
+ assertTrue("Agent-based allocation failed", plan.getAllReservations()
|
|
|
|
+ .size() == numJobsInScenario + 1);
|
|
|
|
+
|
|
|
|
+ // Get reservation
|
|
|
|
+ ReservationAllocation alloc1 = plan.getReservationById(reservationID);
|
|
|
|
+
|
|
|
|
+ // Verify allocation
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 10 * step, 11 * step, 20, 1024, 1));
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 14 * step, 15 * step, 20, 1024, 1));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testAllImpossible() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Prepare basic plan
|
|
|
|
+ int numJobsInScenario = initializeScenario2();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] {
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ step), // Duration
|
|
|
|
+ ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ 2 * step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ try {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+ fail();
|
|
|
|
+ } catch (PlanningException e) {
|
|
|
|
+ // Expected failure
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was not accepted
|
|
|
|
+ assertTrue("Agent-based allocation should have failed", plan
|
|
|
|
+ .getAllReservations().size() == numJobsInScenario);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testUpdate() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Create flexible reservation
|
|
|
|
+ ReservationDefinition rrFlex =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 14 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 100, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 2 * step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Create blocking reservation
|
|
|
|
+ ReservationDefinition rrBlock =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 11 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 100, // Num containers
|
|
|
|
+ 100, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Create reservation IDs
|
|
|
|
+ ReservationId flexReservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ ReservationId blockReservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+
|
|
|
|
+ // Add block, add flex, remove block, update flex
|
|
|
|
+ agent.createReservation(blockReservationID, "uBlock", plan, rrBlock);
|
|
|
|
+ agent.createReservation(flexReservationID, "uFlex", plan, rrFlex);
|
|
|
|
+ agent.deleteReservation(blockReservationID, "uBlock", plan);
|
|
|
|
+ agent.updateReservation(flexReservationID, "uFlex", plan, rrFlex);
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was accepted
|
|
|
|
+ assertTrue("Agent-based allocation failed", flexReservationID != null);
|
|
|
|
+ assertTrue("Agent-based allocation failed", plan.getAllReservations()
|
|
|
|
+ .size() == 1);
|
|
|
|
+
|
|
|
|
+ // Get reservation
|
|
|
|
+ ReservationAllocation alloc1 = plan.getReservationById(flexReservationID);
|
|
|
|
+
|
|
|
|
+ // Verify allocation
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 10 * step, 14 * step, 50, 1024, 1));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testImpossibleDuration() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 15 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 20, // Num containers
|
|
|
|
+ 20, // Concurrency
|
|
|
|
+ 10 * step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ try {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+ fail();
|
|
|
|
+ } catch (PlanningException e) {
|
|
|
|
+ // Expected failure
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was not accepted
|
|
|
|
+ assertTrue("Agent-based allocation should have failed", plan
|
|
|
|
+ .getAllReservations().size() == 0);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testLoadedDurationIntervals() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ int numJobsInScenario = initializeScenario3();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr1 =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 13 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 80, // Num containers
|
|
|
|
+ 10, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u1", plan, rr1);
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was accepted
|
|
|
|
+ assertTrue("Agent-based allocation failed", reservationID != null);
|
|
|
|
+ assertTrue("Agent-based allocation failed", plan.getAllReservations()
|
|
|
|
+ .size() == numJobsInScenario + 1);
|
|
|
|
+
|
|
|
|
+ // Get reservation
|
|
|
|
+ ReservationAllocation alloc1 = plan.getReservationById(reservationID);
|
|
|
|
+
|
|
|
|
+ // Verify allocation
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 10 * step, 11 * step, 20, 1024, 1));
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 11 * step, 12 * step, 20, 1024, 1));
|
|
|
|
+ assertTrue(alloc1.toString(),
|
|
|
|
+ check(alloc1, 12 * step, 13 * step, 40, 1024, 1));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testCostFunction() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // Create large memory reservation
|
|
|
|
+ ReservationDefinition rr7Mem1Core =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 11 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(7 * 1024, 1),// Capability
|
|
|
|
+ 1, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1");
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr6Mem6Cores =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 11 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(6 * 1024, 6),// Capability
|
|
|
|
+ 1, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u2");
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ ReservationDefinition rr =
|
|
|
|
+ createReservationDefinition(
|
|
|
|
+ 10 * step, // Job arrival time
|
|
|
|
+ 12 * step, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 1, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ step) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u3");
|
|
|
|
+
|
|
|
|
+ // Create reservation IDs
|
|
|
|
+ ReservationId reservationID1 =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ ReservationId reservationID2 =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ ReservationId reservationID3 =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+
|
|
|
|
+ // Add all
|
|
|
|
+ agent.createReservation(reservationID1, "u1", plan, rr7Mem1Core);
|
|
|
|
+ agent.createReservation(reservationID2, "u2", plan, rr6Mem6Cores);
|
|
|
|
+ agent.createReservation(reservationID3, "u3", plan, rr);
|
|
|
|
+
|
|
|
|
+ // Get reservation
|
|
|
|
+ ReservationAllocation alloc3 = plan.getReservationById(reservationID3);
|
|
|
|
+
|
|
|
|
+ assertTrue(alloc3.toString(),
|
|
|
|
+ check(alloc3, 10 * step, 11 * step, 0, 1024, 1));
|
|
|
|
+ assertTrue(alloc3.toString(),
|
|
|
|
+ check(alloc3, 11 * step, 12 * step, 1, 1024, 1));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testFromCluster() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // int numJobsInScenario = initializeScenario3();
|
|
|
|
+
|
|
|
|
+ List<ReservationDefinition> list = new ArrayList<ReservationDefinition>();
|
|
|
|
+
|
|
|
|
+ // Create reservation
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716392178L, // Job arrival time
|
|
|
|
+ 1425722262791L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 7, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 587000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u1"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716406178L, // Job arrival time
|
|
|
|
+ 1425721255841L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 6, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 485000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u2"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716399178L, // Job arrival time
|
|
|
|
+ 1425723780138L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 6, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 738000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u3"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716437178L, // Job arrival time
|
|
|
|
+ 1425722968378L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 7, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 653000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u4"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716406178L, // Job arrival time
|
|
|
|
+ 1425721926090L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 6, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 552000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u5"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716379178L, // Job arrival time
|
|
|
|
+ 1425722238553L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 6, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 586000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u6"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716407178L, // Job arrival time
|
|
|
|
+ 1425722908317L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 7, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 650000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u7"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716452178L, // Job arrival time
|
|
|
|
+ 1425722841562L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 6, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 639000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u8"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716384178L, // Job arrival time
|
|
|
|
+ 1425721766129L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 7, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 538000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u9"));
|
|
|
|
+
|
|
|
|
+ list.add(createReservationDefinition(
|
|
|
|
+ 1425716437178L, // Job arrival time
|
|
|
|
+ 1425722507886L, // Job deadline
|
|
|
|
+ new ReservationRequest[] { ReservationRequest.newInstance(
|
|
|
|
+ Resource.newInstance(1024, 1), // Capability
|
|
|
|
+ 5, // Num containers
|
|
|
|
+ 1, // Concurrency
|
|
|
|
+ 607000) }, // Duration
|
|
|
|
+ ReservationRequestInterpreter.R_ALL, "u10"));
|
|
|
|
+
|
|
|
|
+ // Add reservation
|
|
|
|
+ int i = 1;
|
|
|
|
+ for (ReservationDefinition rr : list) {
|
|
|
|
+ ReservationId reservationID =
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId();
|
|
|
|
+ agent.createReservation(reservationID, "u" + Integer.toString(i), plan,
|
|
|
|
+ rr);
|
|
|
|
+ ++i;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // CHECK: allocation was accepted
|
|
|
|
+ assertTrue("Agent-based allocation failed", plan.getAllReservations()
|
|
|
|
+ .size() == list.size());
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Before
|
|
|
|
+ public void setup() throws Exception {
|
|
|
|
+
|
|
|
|
+ // Initialize random seed
|
|
|
|
+ long seed = rand.nextLong();
|
|
|
|
+ rand.setSeed(seed);
|
|
|
|
+ Log.info("Running with seed: " + seed);
|
|
|
|
+
|
|
|
|
+ // Set cluster parameters
|
|
|
|
+ long timeWindow = 1000000L;
|
|
|
|
+ int capacityMem = 100 * 1024;
|
|
|
|
+ int capacityCores = 100;
|
|
|
|
+ step = 60000L;
|
|
|
|
+
|
|
|
|
+ Resource clusterCapacity = Resource.newInstance(capacityMem, capacityCores);
|
|
|
|
+
|
|
|
|
+ // Set configuration
|
|
|
|
+ ReservationSystemTestUtil testUtil = new ReservationSystemTestUtil();
|
|
|
|
+ String reservationQ = testUtil.getFullReservationQueueName();
|
|
|
|
+ float instConstraint = 100;
|
|
|
|
+ float avgConstraint = 100;
|
|
|
|
+
|
|
|
|
+ ReservationSchedulerConfiguration conf =
|
|
|
|
+ ReservationSystemTestUtil.createConf(reservationQ, timeWindow,
|
|
|
|
+ instConstraint, avgConstraint);
|
|
|
|
+
|
|
|
|
+ CapacityOverTimePolicy policy = new CapacityOverTimePolicy();
|
|
|
|
+ policy.init(reservationQ, conf);
|
|
|
|
+
|
|
|
|
+ QueueMetrics queueMetrics = mock(QueueMetrics.class);
|
|
|
|
+
|
|
|
|
+ // Set planning agent
|
|
|
|
+ agent = new AlignedPlannerWithGreedy();
|
|
|
|
+
|
|
|
|
+ // Create Plan
|
|
|
|
+ plan =
|
|
|
|
+ new InMemoryPlan(queueMetrics, policy, agent, clusterCapacity, step,
|
|
|
|
+ res, minAlloc, maxAlloc, "dedicated", null, true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int initializeScenario1() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // insert in the reservation a couple of controlled reservations, to create
|
|
|
|
+ // conditions for assignment that are non-empty
|
|
|
|
+
|
|
|
|
+ addFixedAllocation(0L, step, new int[] { 10, 10, 20, 20, 20, 10, 10 });
|
|
|
|
+
|
|
|
|
+ System.out.println("--------BEFORE AGENT----------");
|
|
|
|
+ System.out.println(plan.toString());
|
|
|
|
+ System.out.println(plan.toCumulativeString());
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int initializeScenario2() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // insert in the reservation a couple of controlled reservations, to create
|
|
|
|
+ // conditions for assignment that are non-empty
|
|
|
|
+
|
|
|
|
+ addFixedAllocation(11 * step, step, new int[] { 90, 90, 90 });
|
|
|
|
+
|
|
|
|
+ System.out.println("--------BEFORE AGENT----------");
|
|
|
|
+ System.out.println(plan.toString());
|
|
|
|
+ System.out.println(plan.toCumulativeString());
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int initializeScenario3() throws PlanningException {
|
|
|
|
+
|
|
|
|
+ // insert in the reservation a couple of controlled reservations, to create
|
|
|
|
+ // conditions for assignment that are non-empty
|
|
|
|
+
|
|
|
|
+ addFixedAllocation(10 * step, step, new int[] { 70, 80, 60 });
|
|
|
|
+
|
|
|
|
+ System.out.println("--------BEFORE AGENT----------");
|
|
|
|
+ System.out.println(plan.toString());
|
|
|
|
+ System.out.println(plan.toCumulativeString());
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void addFixedAllocation(long start, long step, int[] f)
|
|
|
|
+ throws PlanningException {
|
|
|
|
+
|
|
|
|
+ assertTrue(plan.toString(),
|
|
|
|
+ plan.addReservation(new InMemoryReservationAllocation(
|
|
|
|
+ ReservationSystemTestUtil.getNewReservationId(), null,
|
|
|
|
+ "user_fixed", "dedicated", start, start + f.length * step,
|
|
|
|
+ ReservationSystemTestUtil.generateAllocation(start, step, f), res,
|
|
|
|
+ minAlloc)));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private ReservationDefinition createReservationDefinition(long arrival,
|
|
|
|
+ long deadline, ReservationRequest[] reservationRequests,
|
|
|
|
+ ReservationRequestInterpreter rType, String username) {
|
|
|
|
+
|
|
|
|
+ return ReservationDefinition.newInstance(arrival, deadline,
|
|
|
|
+ ReservationRequests.newInstance(Arrays.asList(reservationRequests),
|
|
|
|
+ rType), username);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean check(ReservationAllocation alloc, long start, long end,
|
|
|
|
+ int containers, int mem, int cores) {
|
|
|
|
+
|
|
|
|
+ Resource expectedResources =
|
|
|
|
+ Resource.newInstance(mem * containers, cores * containers);
|
|
|
|
+
|
|
|
|
+ // Verify that all allocations in [start,end) equal containers * (mem,cores)
|
|
|
|
+ for (long i = start; i < end; i++) {
|
|
|
|
+ if (!Resources.equals(alloc.getResourcesAtTime(i), expectedResources)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|