YARN-5329. Placement Agent enhancements required to support recurring reservations in ReservationSystem. (Carlo Curino via Subru).
(cherry picked from commit e6e614e380
)
This commit is contained in:
parent
7836a6b59a
commit
7fd4a997f4
|
@ -723,6 +723,12 @@ public class InMemoryPlan implements Plan {
|
||||||
+ periodicRle.getTimePeriod() + ")");
|
+ periodicRle.getTimePeriod() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (period < (end - start)) {
|
||||||
|
throw new PlanningException(
|
||||||
|
"Invalid input: (end - start) = (" + end + " - " + start + ") = "
|
||||||
|
+ (end - start) + " > period = " + period);
|
||||||
|
}
|
||||||
|
|
||||||
// find the minimum resources available among all the instances that fit
|
// find the minimum resources available among all the instances that fit
|
||||||
// in the LCM
|
// in the LCM
|
||||||
long numInstInLCM = periodicRle.getTimePeriod() / period;
|
long numInstInLCM = periodicRle.getTimePeriod() / period;
|
||||||
|
|
|
@ -221,7 +221,8 @@ public class PeriodicRLESparseResourceAllocation
|
||||||
NavigableMap<Long, Resource> cumulativeMap = this.getCumulative();
|
NavigableMap<Long, Resource> cumulativeMap = this.getCumulative();
|
||||||
Long previous = cumulativeMap.floorKey(relativeStart);
|
Long previous = cumulativeMap.floorKey(relativeStart);
|
||||||
previous = (previous != null) ? previous : 0;
|
previous = (previous != null) ? previous : 0;
|
||||||
for (long i = 0; i <= (end - start) / timePeriod; i++) {
|
//make sure to go one past end, to catch end times extending past period
|
||||||
|
for (long i = 0; i <= 1 + (end - start) / timePeriod; i++) {
|
||||||
for (Map.Entry<Long, Resource> e : cumulativeMap.entrySet()) {
|
for (Map.Entry<Long, Resource> e : cumulativeMap.entrySet()) {
|
||||||
long curKey = e.getKey() + (i * timePeriod);
|
long curKey = e.getKey() + (i * timePeriod);
|
||||||
if (curKey >= previous && (start + curKey - relativeStart) <= end) {
|
if (curKey >= previous && (start + curKey - relativeStart) <= end) {
|
||||||
|
|
|
@ -423,7 +423,8 @@ public class RLESparseResourceAllocation {
|
||||||
Resource outRes) {
|
Resource outRes) {
|
||||||
|
|
||||||
if (out.isEmpty() || (out.lastEntry() != null && outRes == null)
|
if (out.isEmpty() || (out.lastEntry() != null && outRes == null)
|
||||||
|| !Resources.equals(out.lastEntry().getValue(), outRes)) {
|
|| (out.lastEntry().getValue() != null
|
||||||
|
&& !Resources.equals(out.lastEntry().getValue(), outRes))) {
|
||||||
out.put(time, outRes);
|
out.put(time, outRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +461,8 @@ public class RLESparseResourceAllocation {
|
||||||
if (!Resources.fitsIn(b, a)) {
|
if (!Resources.fitsIn(b, a)) {
|
||||||
throw new PlanningException(
|
throw new PlanningException(
|
||||||
"RLESparseResourceAllocation: merge failed as the "
|
"RLESparseResourceAllocation: merge failed as the "
|
||||||
+ "resulting RLESparseResourceAllocation would be negative");
|
+ "resulting RLESparseResourceAllocation would "
|
||||||
|
+ "be negative, when testing: (" + eB + ") > (" + eA + ")");
|
||||||
} else {
|
} else {
|
||||||
return Resources.subtract(a, b);
|
return Resources.subtract(a, b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,12 @@ public class IterativePlanner extends PlanningAlgorithm {
|
||||||
// Current stage
|
// Current stage
|
||||||
ReservationRequest currentReservationStage;
|
ReservationRequest currentReservationStage;
|
||||||
|
|
||||||
|
// initialize periodicity
|
||||||
|
long period = 0;
|
||||||
|
if(reservation.getRecurrenceExpression() != null){
|
||||||
|
period = Long.parseLong(reservation.getRecurrenceExpression());
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate the stages in reverse order
|
// Iterate the stages in reverse order
|
||||||
while (stageProvider.hasNext()) {
|
while (stageProvider.hasNext()) {
|
||||||
|
|
||||||
|
@ -117,7 +123,7 @@ public class IterativePlanner extends PlanningAlgorithm {
|
||||||
// Compute stage allocation
|
// Compute stage allocation
|
||||||
Map<ReservationInterval, Resource> curAlloc =
|
Map<ReservationInterval, Resource> curAlloc =
|
||||||
computeStageAllocation(plan, currentReservationStage, stageArrival,
|
computeStageAllocation(plan, currentReservationStage, stageArrival,
|
||||||
stageDeadline, user, reservationId);
|
stageDeadline, period, user, reservationId);
|
||||||
|
|
||||||
// If we did not find an allocation, return NULL
|
// If we did not find an allocation, return NULL
|
||||||
// (unless it's an ANY job, then we simply continue).
|
// (unless it's an ANY job, then we simply continue).
|
||||||
|
@ -216,11 +222,10 @@ public class IterativePlanner extends PlanningAlgorithm {
|
||||||
planLoads = plan.getCumulativeLoadOverTime(jobArrival, jobDeadline);
|
planLoads = plan.getCumulativeLoadOverTime(jobArrival, jobDeadline);
|
||||||
ReservationAllocation oldRes = plan.getReservationById(reservationId);
|
ReservationAllocation oldRes = plan.getReservationById(reservationId);
|
||||||
if (oldRes != null) {
|
if (oldRes != null) {
|
||||||
planLoads =
|
planLoads = RLESparseResourceAllocation.merge(
|
||||||
RLESparseResourceAllocation.merge(plan.getResourceCalculator(),
|
plan.getResourceCalculator(), plan.getTotalCapacity(), planLoads,
|
||||||
plan.getTotalCapacity(), planLoads,
|
oldRes.getResourcesOverTime(jobArrival, jobDeadline),
|
||||||
oldRes.getResourcesOverTime(), RLEOperator.subtract, jobArrival,
|
RLEOperator.subtract, jobArrival, jobDeadline);
|
||||||
jobDeadline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,13 +314,13 @@ public class IterativePlanner extends PlanningAlgorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call algStageAllocator
|
// Call algStageAllocator
|
||||||
protected Map<ReservationInterval, Resource> computeStageAllocation(
|
protected Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
||||||
Plan plan, ReservationRequest rr, long stageArrivalTime,
|
ReservationRequest rr, long stageArrivalTime, long stageDeadline,
|
||||||
long stageDeadline, String user, ReservationId oldId)
|
long period, String user, ReservationId oldId) throws PlanningException {
|
||||||
throws PlanningException {
|
|
||||||
|
|
||||||
return algStageAllocator.computeStageAllocation(plan, planLoads,
|
return algStageAllocator.computeStageAllocation(plan, planLoads,
|
||||||
planModifications, rr, stageArrivalTime, stageDeadline, user, oldId);
|
planModifications, rr, stageArrivalTime, stageDeadline, period, user,
|
||||||
|
oldId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.hadoop.yarn.api.records.ReservationDefinition;
|
||||||
import org.apache.hadoop.yarn.api.records.ReservationId;
|
import org.apache.hadoop.yarn.api.records.ReservationId;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.reservation.InMemoryReservationAllocation;
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.InMemoryReservationAllocation;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.PeriodicRLESparseResourceAllocation;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan;
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.Plan;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation;
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationAllocation;
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationAllocation;
|
||||||
|
@ -63,21 +64,33 @@ public abstract class PlanningAlgorithm implements ReservationAgent {
|
||||||
|
|
||||||
// Compute the job allocation
|
// Compute the job allocation
|
||||||
RLESparseResourceAllocation allocation =
|
RLESparseResourceAllocation allocation =
|
||||||
computeJobAllocation(plan, reservationId, adjustedContract, user);
|
computeJobAllocation(plan, reservationId, adjustedContract, user);
|
||||||
|
|
||||||
|
long period = Long.parseLong(contract.getRecurrenceExpression());
|
||||||
|
|
||||||
|
// Make allocation periodic if request is periodic
|
||||||
|
if (contract.getRecurrenceExpression() != null) {
|
||||||
|
if (period > 0) {
|
||||||
|
allocation =
|
||||||
|
new PeriodicRLESparseResourceAllocation(allocation, period);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If no job allocation was found, fail
|
// If no job allocation was found, fail
|
||||||
if (allocation == null) {
|
if (allocation == null) {
|
||||||
throw new PlanningException(
|
throw new PlanningException(
|
||||||
"The planning algorithm could not find a valid allocation"
|
"The planning algorithm could not find a valid allocation"
|
||||||
+ " for your request");
|
+ " for your request");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate the allocation to a map (with zero paddings)
|
// Translate the allocation to a map (with zero paddings)
|
||||||
long step = plan.getStep();
|
long step = plan.getStep();
|
||||||
|
|
||||||
long jobArrival = stepRoundUp(adjustedContract.getArrival(), step);
|
long jobArrival = stepRoundUp(adjustedContract.getArrival(), step);
|
||||||
long jobDeadline = stepRoundUp(adjustedContract.getDeadline(), step);
|
long jobDeadline = stepRoundUp(adjustedContract.getDeadline(), step);
|
||||||
|
|
||||||
Map<ReservationInterval, Resource> mapAllocations =
|
Map<ReservationInterval, Resource> mapAllocations =
|
||||||
allocationsToPaddedMap(allocation, jobArrival, jobDeadline);
|
allocationsToPaddedMap(allocation, jobArrival, jobDeadline, period);
|
||||||
|
|
||||||
// Create the reservation
|
// Create the reservation
|
||||||
ReservationAllocation capReservation =
|
ReservationAllocation capReservation =
|
||||||
|
@ -85,8 +98,7 @@ public abstract class PlanningAlgorithm implements ReservationAgent {
|
||||||
adjustedContract, // Contract
|
adjustedContract, // Contract
|
||||||
user, // User name
|
user, // User name
|
||||||
plan.getQueueName(), // Queue name
|
plan.getQueueName(), // Queue name
|
||||||
findEarliestTime(mapAllocations), // Earliest start time
|
adjustedContract.getArrival(), adjustedContract.getDeadline(),
|
||||||
findLatestTime(mapAllocations), // Latest end time
|
|
||||||
mapAllocations, // Allocations
|
mapAllocations, // Allocations
|
||||||
plan.getResourceCalculator(), // Resource calculator
|
plan.getResourceCalculator(), // Resource calculator
|
||||||
plan.getMinimumAllocation()); // Minimum allocation
|
plan.getMinimumAllocation()); // Minimum allocation
|
||||||
|
@ -100,33 +112,46 @@ public abstract class PlanningAlgorithm implements ReservationAgent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<ReservationInterval, Resource>
|
private Map<ReservationInterval, Resource> allocationsToPaddedMap(
|
||||||
allocationsToPaddedMap(RLESparseResourceAllocation allocation,
|
RLESparseResourceAllocation allocation, long jobArrival, long jobDeadline,
|
||||||
long jobArrival, long jobDeadline) {
|
long period) {
|
||||||
|
|
||||||
// Allocate
|
|
||||||
Map<ReservationInterval, Resource> mapAllocations =
|
|
||||||
allocation.toIntervalMap();
|
|
||||||
|
|
||||||
// Zero allocation
|
// Zero allocation
|
||||||
Resource zeroResource = Resource.newInstance(0, 0);
|
Resource zeroResource = Resource.newInstance(0, 0);
|
||||||
|
|
||||||
// Pad at the beginning
|
if (period > 0) {
|
||||||
long earliestStart = findEarliestTime(mapAllocations);
|
if ((jobDeadline - jobArrival) >= period) {
|
||||||
if (jobArrival < earliestStart) {
|
allocation.addInterval(new ReservationInterval(0L, period),
|
||||||
mapAllocations.put(new ReservationInterval(jobArrival, earliestStart),
|
zeroResource);
|
||||||
zeroResource);
|
}
|
||||||
|
jobArrival = jobArrival % period;
|
||||||
|
jobDeadline = jobDeadline % period;
|
||||||
|
|
||||||
|
if (jobArrival <= jobDeadline) {
|
||||||
|
allocation.addInterval(new ReservationInterval(0, jobArrival),
|
||||||
|
zeroResource);
|
||||||
|
allocation.addInterval(new ReservationInterval(jobDeadline, period),
|
||||||
|
zeroResource);
|
||||||
|
} else {
|
||||||
|
allocation.addInterval(new ReservationInterval(jobDeadline, jobArrival),
|
||||||
|
zeroResource);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Pad at the beginning
|
||||||
|
long earliestStart = findEarliestTime(allocation.toIntervalMap());
|
||||||
|
if (jobArrival < earliestStart) {
|
||||||
|
allocation.addInterval(
|
||||||
|
new ReservationInterval(jobArrival, earliestStart), zeroResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad at the beginning
|
||||||
|
long latestEnd = findLatestTime(allocation.toIntervalMap());
|
||||||
|
if (latestEnd < jobDeadline) {
|
||||||
|
allocation.addInterval(new ReservationInterval(latestEnd, jobDeadline),
|
||||||
|
zeroResource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return allocation.toIntervalMap();
|
||||||
// Pad at the beginning
|
|
||||||
long latestEnd = findLatestTime(mapAllocations);
|
|
||||||
if (latestEnd < jobDeadline) {
|
|
||||||
mapAllocations.put(new ReservationInterval(latestEnd, jobDeadline),
|
|
||||||
zeroResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapAllocations;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract RLESparseResourceAllocation computeJobAllocation(Plan plan,
|
public abstract RLESparseResourceAllocation computeJobAllocation(Plan plan,
|
||||||
|
|
|
@ -45,6 +45,7 @@ public interface StageAllocator {
|
||||||
* the stage by the two phase planning algorithm
|
* the stage by the two phase planning algorithm
|
||||||
* @param stageDeadline the deadline of the stage set by the two phase
|
* @param stageDeadline the deadline of the stage set by the two phase
|
||||||
* planning algorithm
|
* planning algorithm
|
||||||
|
* @param period the periodicity with which this stage appears
|
||||||
* @param user name of the user
|
* @param user name of the user
|
||||||
* @param oldId identifier of the old reservation
|
* @param oldId identifier of the old reservation
|
||||||
*
|
*
|
||||||
|
@ -55,7 +56,7 @@ public interface StageAllocator {
|
||||||
Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
||||||
RLESparseResourceAllocation planLoads,
|
RLESparseResourceAllocation planLoads,
|
||||||
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
||||||
long stageArrival, long stageDeadline, String user,
|
long stageArrival, long stageDeadline, long period, String user,
|
||||||
ReservationId oldId) throws PlanningException;
|
ReservationId oldId) throws PlanningException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class StageAllocatorGreedy implements StageAllocator {
|
||||||
public Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
public Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
||||||
RLESparseResourceAllocation planLoads,
|
RLESparseResourceAllocation planLoads,
|
||||||
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
||||||
long stageEarliestStart, long stageDeadline, String user,
|
long stageEarliestStart, long stageDeadline, long period, String user,
|
||||||
ReservationId oldId) throws PlanningException {
|
ReservationId oldId) throws PlanningException {
|
||||||
|
|
||||||
Resource totalCapacity = plan.getTotalCapacity();
|
Resource totalCapacity = plan.getTotalCapacity();
|
||||||
|
@ -69,7 +69,7 @@ public class StageAllocatorGreedy implements StageAllocator {
|
||||||
|
|
||||||
RLESparseResourceAllocation netAvailable =
|
RLESparseResourceAllocation netAvailable =
|
||||||
plan.getAvailableResourceOverTime(user, oldId, stageEarliestStart,
|
plan.getAvailableResourceOverTime(user, oldId, stageEarliestStart,
|
||||||
stageDeadline, 0);
|
stageDeadline, period);
|
||||||
|
|
||||||
netAvailable =
|
netAvailable =
|
||||||
RLESparseResourceAllocation.merge(plan.getResourceCalculator(),
|
RLESparseResourceAllocation.merge(plan.getResourceCalculator(),
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class StageAllocatorGreedyRLE implements StageAllocator {
|
||||||
public Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
public Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
||||||
RLESparseResourceAllocation planLoads,
|
RLESparseResourceAllocation planLoads,
|
||||||
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
||||||
long stageEarliestStart, long stageDeadline, String user,
|
long stageEarliestStart, long stageDeadline, long period, String user,
|
||||||
ReservationId oldId) throws PlanningException {
|
ReservationId oldId) throws PlanningException {
|
||||||
|
|
||||||
// abort early if the interval is not satisfiable
|
// abort early if the interval is not satisfiable
|
||||||
|
@ -83,8 +83,9 @@ public class StageAllocatorGreedyRLE implements StageAllocator {
|
||||||
int gangsToPlace = rr.getNumContainers() / rr.getConcurrency();
|
int gangsToPlace = rr.getNumContainers() / rr.getConcurrency();
|
||||||
|
|
||||||
// get available resources from plan
|
// get available resources from plan
|
||||||
RLESparseResourceAllocation netRLERes = plan.getAvailableResourceOverTime(
|
RLESparseResourceAllocation netRLERes =
|
||||||
user, oldId, stageEarliestStart, stageDeadline, 0);
|
plan.getAvailableResourceOverTime(user, oldId, stageEarliestStart,
|
||||||
|
stageDeadline, period);
|
||||||
|
|
||||||
// remove plan modifications
|
// remove plan modifications
|
||||||
netRLERes =
|
netRLERes =
|
||||||
|
|
|
@ -70,15 +70,15 @@ public class StageAllocatorLowCostAligned implements StageAllocator {
|
||||||
public Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
public Map<ReservationInterval, Resource> computeStageAllocation(Plan plan,
|
||||||
RLESparseResourceAllocation planLoads,
|
RLESparseResourceAllocation planLoads,
|
||||||
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
RLESparseResourceAllocation planModifications, ReservationRequest rr,
|
||||||
long stageArrival, long stageDeadline, String user, ReservationId oldId)
|
long stageArrival, long stageDeadline, long period, String user,
|
||||||
throws PlanningException {
|
ReservationId oldId) throws PlanningException {
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
ResourceCalculator resCalc = plan.getResourceCalculator();
|
ResourceCalculator resCalc = plan.getResourceCalculator();
|
||||||
Resource capacity = plan.getTotalCapacity();
|
Resource capacity = plan.getTotalCapacity();
|
||||||
|
|
||||||
RLESparseResourceAllocation netRLERes = plan.getAvailableResourceOverTime(
|
RLESparseResourceAllocation netRLERes = plan.getAvailableResourceOverTime(
|
||||||
user, oldId, stageArrival, stageDeadline, 0);
|
user, oldId, stageArrival, stageDeadline, period);
|
||||||
|
|
||||||
long step = plan.getStep();
|
long step = plan.getStep();
|
||||||
|
|
||||||
|
|
|
@ -180,8 +180,12 @@ public abstract class BaseSharingPolicyTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(rStart > rEnd){
|
||||||
rle.addInterval(new ReservationInterval(rStart, rEnd), alloc);
|
rle.addInterval(new ReservationInterval(rStart, period), alloc);
|
||||||
|
rle.addInterval(new ReservationInterval(0, rEnd), alloc);
|
||||||
|
} else {
|
||||||
|
rle.addInterval(new ReservationInterval(rStart, rEnd), alloc);
|
||||||
|
}
|
||||||
return rle;
|
return rle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.jcip.annotations.NotThreadSafe;
|
import net.jcip.annotations.NotThreadSafe;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.ContractValidationException;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningException;
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningException;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningQuotaException;
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningQuotaException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -39,63 +40,67 @@ public class TestCapacityOverTimePolicy extends BaseSharingPolicyTest {
|
||||||
final static long ONEDAY = 86400 * 1000;
|
final static long ONEDAY = 86400 * 1000;
|
||||||
final static long ONEHOUR = 3600 * 1000;
|
final static long ONEHOUR = 3600 * 1000;
|
||||||
final static long ONEMINUTE = 60 * 1000;
|
final static long ONEMINUTE = 60 * 1000;
|
||||||
final static String TWODAYPERIOD = "7200000";
|
final static String TWOHOURPERIOD = "7200000";
|
||||||
final static String ONEDAYPERIOD = "86400000";
|
final static String ONEDAYPERIOD = "86400000";
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "Duration {0}, height {1}," +
|
@Parameterized.Parameters(name = "Duration {0}, height {1}," +
|
||||||
" submission {2}, periodic {3})")
|
" numSubmission {2}, periodic {3})")
|
||||||
public static Collection<Object[]> data() {
|
public static Collection<Object[]> data() {
|
||||||
return Arrays.asList(new Object[][] {
|
return Arrays.asList(new Object[][] {
|
||||||
|
|
||||||
// easy fit
|
// easy fit
|
||||||
{ONEHOUR, 0.25, 1, null, null },
|
{ONEHOUR, 0.25, 1, null, null },
|
||||||
{ONEHOUR, 0.25, 1, TWODAYPERIOD, null },
|
{ONEHOUR, 0.25, 1, TWOHOURPERIOD, null },
|
||||||
{ONEHOUR, 0.25, 1, ONEDAYPERIOD, null },
|
{ONEHOUR, 0.25, 1, ONEDAYPERIOD, null },
|
||||||
|
|
||||||
// instantaneous high, but fit integral and inst limits
|
// instantaneous high, but fit integral and inst limits
|
||||||
{ONEMINUTE, 0.74, 1, null, null },
|
{ONEMINUTE, 0.74, 1, null, null },
|
||||||
{ONEMINUTE, 0.74, 1, TWODAYPERIOD, null },
|
{ONEMINUTE, 0.74, 1, TWOHOURPERIOD, null },
|
||||||
{ONEMINUTE, 0.74, 1, ONEDAYPERIOD, null },
|
{ONEMINUTE, 0.74, 1, ONEDAYPERIOD, null },
|
||||||
|
|
||||||
// barely fit
|
// barely fit
|
||||||
{ONEHOUR, 0.76, 1, null, PlanningQuotaException.class },
|
{ONEHOUR, 0.76, 1, null, PlanningQuotaException.class },
|
||||||
{ONEHOUR, 0.76, 1, TWODAYPERIOD, PlanningQuotaException.class },
|
{ONEHOUR, 0.76, 1, TWOHOURPERIOD, PlanningQuotaException.class },
|
||||||
{ONEHOUR, 0.76, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
{ONEHOUR, 0.76, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
||||||
|
|
||||||
// overcommit with single reservation
|
// overcommit with single reservation
|
||||||
{ONEHOUR, 1.1, 1, null, PlanningQuotaException.class },
|
{ONEHOUR, 1.1, 1, null, PlanningQuotaException.class },
|
||||||
{ONEHOUR, 1.1, 1, TWODAYPERIOD, PlanningQuotaException.class },
|
{ONEHOUR, 1.1, 1, TWOHOURPERIOD, PlanningQuotaException.class },
|
||||||
{ONEHOUR, 1.1, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
{ONEHOUR, 1.1, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
||||||
|
|
||||||
// barely fit with multiple reservations (instantaneously, lowering to
|
// barely fit with multiple reservations (instantaneously, lowering to
|
||||||
// 1min to fit integral)
|
// 1min to fit integral)
|
||||||
{ONEMINUTE, 0.25, 3, null, null },
|
{ONEMINUTE, 0.25, 3, null, null },
|
||||||
{ONEMINUTE, 0.25, 3, TWODAYPERIOD, null },
|
{ONEMINUTE, 0.25, 3, TWOHOURPERIOD, null },
|
||||||
{ONEMINUTE, 0.25, 3, ONEDAYPERIOD, null },
|
{ONEMINUTE, 0.25, 3, ONEDAYPERIOD, null },
|
||||||
|
|
||||||
// overcommit with multiple reservations (instantaneously)
|
// overcommit with multiple reservations (instantaneously)
|
||||||
{ONEMINUTE, 0.25, 4, null, PlanningQuotaException.class },
|
{ONEMINUTE, 0.25, 4, null, PlanningQuotaException.class },
|
||||||
{ONEMINUTE, 0.25, 4, TWODAYPERIOD, PlanningQuotaException.class },
|
{ONEMINUTE, 0.25, 4, TWOHOURPERIOD, PlanningQuotaException.class },
|
||||||
{ONEMINUTE, 0.25, 4, ONEDAYPERIOD, PlanningQuotaException.class },
|
{ONEMINUTE, 0.25, 4, ONEDAYPERIOD, PlanningQuotaException.class },
|
||||||
|
|
||||||
// (non-periodic) reservation longer than window
|
// (non-periodic) reservation longer than window
|
||||||
{25 * ONEHOUR, 0.25, 1, null, PlanningQuotaException.class },
|
{25 * ONEHOUR, 0.25, 1, null, PlanningQuotaException.class },
|
||||||
{25 * ONEHOUR, 0.25, 1, TWODAYPERIOD, PlanningQuotaException.class },
|
// NOTE: we generally don't accept periodicity < duration but the test
|
||||||
|
// generator will "wrap" this correctly
|
||||||
|
{25 * ONEHOUR, 0.25, 1, TWOHOURPERIOD, PlanningQuotaException.class },
|
||||||
{25 * ONEHOUR, 0.25, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
{25 * ONEHOUR, 0.25, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
||||||
|
|
||||||
// (non-periodic) reservation longer than window
|
// (non-periodic) reservation longer than window
|
||||||
{25 * ONEHOUR, 0.05, 5, null, PlanningQuotaException.class },
|
{25 * ONEHOUR, 0.05, 5, null, PlanningQuotaException.class },
|
||||||
{25 * ONEHOUR, 0.05, 5, TWODAYPERIOD, PlanningQuotaException.class },
|
// NOTE: we generally don't accept periodicity < duration but the test
|
||||||
|
// generator will "wrap" this correctly
|
||||||
|
{25 * ONEHOUR, 0.05, 5, TWOHOURPERIOD, PlanningQuotaException.class },
|
||||||
{25 * ONEHOUR, 0.05, 5, ONEDAYPERIOD, PlanningQuotaException.class },
|
{25 * ONEHOUR, 0.05, 5, ONEDAYPERIOD, PlanningQuotaException.class },
|
||||||
|
|
||||||
// overcommit integral
|
// overcommit integral
|
||||||
{ONEDAY, 0.26, 1, null, PlanningQuotaException.class },
|
{ONEDAY, 0.26, 1, null, PlanningQuotaException.class },
|
||||||
{2 * ONEHOUR, 0.26, 1, TWODAYPERIOD, PlanningQuotaException.class },
|
{2 * ONEHOUR, 0.26, 1, TWOHOURPERIOD, PlanningQuotaException.class },
|
||||||
{2 * ONEDAY, 0.26, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
{2 * ONEDAY, 0.26, 1, ONEDAYPERIOD, PlanningQuotaException.class },
|
||||||
|
|
||||||
// overcommit integral
|
// overcommit integral
|
||||||
{ONEDAY / 2, 0.51, 1, null, PlanningQuotaException.class },
|
{ONEDAY / 2, 0.51, 1, null, PlanningQuotaException.class },
|
||||||
{2 * ONEHOUR / 2, 0.51, 1, TWODAYPERIOD,
|
{2 * ONEHOUR / 2, 0.51, 1, TWOHOURPERIOD,
|
||||||
PlanningQuotaException.class },
|
PlanningQuotaException.class },
|
||||||
{2 * ONEDAY / 2, 0.51, 1, ONEDAYPERIOD, PlanningQuotaException.class }
|
{2 * ONEDAY / 2, 0.51, 1, ONEDAYPERIOD, PlanningQuotaException.class }
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.reservation;
|
package org.apache.hadoop.yarn.server.resourcemanager.reservation;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ -119,6 +120,18 @@ public class TestInMemoryPlan {
|
||||||
checkAllocation(plan, alloc, start, 0);
|
checkAllocation(plan, alloc, start, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = PlanningException.class)
|
||||||
|
public void testOutOfRange() throws PlanningException {
|
||||||
|
maxPeriodicity = 100;
|
||||||
|
Plan plan = new InMemoryPlan(queueMetrics, policy, agent, totalCapacity, 1L,
|
||||||
|
resCalc, minAlloc, maxAlloc, planName, replanner, true, maxPeriodicity,
|
||||||
|
context, new UTCClock());
|
||||||
|
|
||||||
|
// we expect the plan to complaint as the range 330-150 > 50
|
||||||
|
RLESparseResourceAllocation availableBefore =
|
||||||
|
plan.getAvailableResourceOverTime(user, null, 150, 330, 50);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddPeriodicReservation() throws PlanningException {
|
public void testAddPeriodicReservation() throws PlanningException {
|
||||||
|
|
||||||
|
@ -146,8 +159,14 @@ public class TestInMemoryPlan {
|
||||||
checkAllocation(plan, alloc, start, period);
|
checkAllocation(plan, alloc, start, period);
|
||||||
|
|
||||||
RLESparseResourceAllocation available =
|
RLESparseResourceAllocation available =
|
||||||
plan.getAvailableResourceOverTime(user, reservationID, 150, 330, 50);
|
plan.getAvailableResourceOverTime(user, null, 130, 170, 50);
|
||||||
System.out.println(available);
|
|
||||||
|
// the reservation has period 20 starting at 10, and the interaction with
|
||||||
|
// the period 50 request means that every 10 we expect a "90GB" point
|
||||||
|
assertEquals(92160, available.getCapacityAtTime(130).getMemorySize());
|
||||||
|
assertEquals(92160, available.getCapacityAtTime(140).getMemorySize());
|
||||||
|
assertEquals(92160, available.getCapacityAtTime(150).getMemorySize());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAllocation(Plan plan, int[] alloc, int start,
|
private void checkAllocation(Plan plan, int[] alloc, int start,
|
||||||
|
@ -162,18 +181,18 @@ public class TestInMemoryPlan {
|
||||||
for (int i = 0; i < alloc.length; i++) {
|
for (int i = 0; i < alloc.length; i++) {
|
||||||
// only one instance for non-periodic reservation
|
// only one instance for non-periodic reservation
|
||||||
if (periodicity <= 0) {
|
if (periodicity <= 0) {
|
||||||
Assert.assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
||||||
plan.getTotalCommittedResources(start + i));
|
plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
||||||
userCons.getCapacityAtTime(start + i));
|
userCons.getCapacityAtTime(start + i));
|
||||||
} else {
|
} else {
|
||||||
// periodic reservations should repeat
|
// periodic reservations should repeat
|
||||||
long y = 0;
|
long y = 0;
|
||||||
Resource res = Resource.newInstance(1024 * (alloc[i]), (alloc[i]));
|
Resource res = Resource.newInstance(1024 * (alloc[i]), (alloc[i]));
|
||||||
while (y <= end * 2) {
|
while (y <= end * 2) {
|
||||||
Assert.assertEquals("At time: " + start + i + y, res,
|
assertEquals("At time: " + start + i + y, res,
|
||||||
plan.getTotalCommittedResources(start + i + y));
|
plan.getTotalCommittedResources(start + i + y));
|
||||||
Assert.assertEquals(" At time: " + (start + i + y), res,
|
assertEquals(" At time: " + (start + i + y), res,
|
||||||
userCons.getCapacityAtTime(start + i + y));
|
userCons.getCapacityAtTime(start + i + y));
|
||||||
y = y + periodicity;
|
y = y + periodicity;
|
||||||
}
|
}
|
||||||
|
@ -253,9 +272,9 @@ public class TestInMemoryPlan {
|
||||||
RLESparseResourceAllocation userCons =
|
RLESparseResourceAllocation userCons =
|
||||||
plan.getConsumptionForUserOverTime(user, start, start + alloc.length);
|
plan.getConsumptionForUserOverTime(user, start, start + alloc.length);
|
||||||
for (int i = 0; i < alloc.length; i++) {
|
for (int i = 0; i < alloc.length; i++) {
|
||||||
Assert.assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
||||||
plan.getTotalCommittedResources(start + i));
|
plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])),
|
||||||
userCons.getCapacityAtTime(start + i));
|
userCons.getCapacityAtTime(start + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,9 +294,9 @@ public class TestInMemoryPlan {
|
||||||
start + updatedAlloc.length);
|
start + updatedAlloc.length);
|
||||||
|
|
||||||
for (int i = 0; i < updatedAlloc.length; i++) {
|
for (int i = 0; i < updatedAlloc.length; i++) {
|
||||||
Assert.assertEquals(Resource.newInstance(1024 * (updatedAlloc[i] + i),
|
assertEquals(Resource.newInstance(1024 * (updatedAlloc[i] + i),
|
||||||
updatedAlloc[i] + i), plan.getTotalCommittedResources(start + i));
|
updatedAlloc[i] + i), plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(Resource.newInstance(1024 * (updatedAlloc[i] + i),
|
assertEquals(Resource.newInstance(1024 * (updatedAlloc[i] + i),
|
||||||
updatedAlloc[i] + i), userCons.getCapacityAtTime(start + i));
|
updatedAlloc[i] + i), userCons.getCapacityAtTime(start + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,10 +390,10 @@ public class TestInMemoryPlan {
|
||||||
plan.getConsumptionForUserOverTime(user, start, start + alloc.length);
|
plan.getConsumptionForUserOverTime(user, start, start + alloc.length);
|
||||||
|
|
||||||
for (int i = 0; i < alloc.length; i++) {
|
for (int i = 0; i < alloc.length; i++) {
|
||||||
Assert.assertEquals(
|
assertEquals(
|
||||||
Resource.newInstance(1024 * (alloc[i] + i), (alloc[i] + i)),
|
Resource.newInstance(1024 * (alloc[i] + i), (alloc[i] + i)),
|
||||||
plan.getTotalCommittedResources(start + i));
|
plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(
|
assertEquals(
|
||||||
Resource.newInstance(1024 * (alloc[i] + i), (alloc[i] + i)),
|
Resource.newInstance(1024 * (alloc[i] + i), (alloc[i] + i)),
|
||||||
userCons.getCapacityAtTime(start + i));
|
userCons.getCapacityAtTime(start + i));
|
||||||
}
|
}
|
||||||
|
@ -389,9 +408,9 @@ public class TestInMemoryPlan {
|
||||||
userCons =
|
userCons =
|
||||||
plan.getConsumptionForUserOverTime(user, start, start + alloc.length);
|
plan.getConsumptionForUserOverTime(user, start, start + alloc.length);
|
||||||
for (int i = 0; i < alloc.length; i++) {
|
for (int i = 0; i < alloc.length; i++) {
|
||||||
Assert.assertEquals(Resource.newInstance(0, 0),
|
assertEquals(Resource.newInstance(0, 0),
|
||||||
plan.getTotalCommittedResources(start + i));
|
plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(Resource.newInstance(0, 0),
|
assertEquals(Resource.newInstance(0, 0),
|
||||||
userCons.getCapacityAtTime(start + i));
|
userCons.getCapacityAtTime(start + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,11 +511,11 @@ public class TestInMemoryPlan {
|
||||||
plan.getConsumptionForUserOverTime(user, start, start + alloc2.length);
|
plan.getConsumptionForUserOverTime(user, start, start + alloc2.length);
|
||||||
|
|
||||||
for (int i = 0; i < alloc2.length; i++) {
|
for (int i = 0; i < alloc2.length; i++) {
|
||||||
Assert.assertEquals(
|
assertEquals(
|
||||||
Resource.newInstance(1024 * (alloc1[i] + alloc2[i] + i),
|
Resource.newInstance(1024 * (alloc1[i] + alloc2[i] + i),
|
||||||
alloc1[i] + alloc2[i] + i),
|
alloc1[i] + alloc2[i] + i),
|
||||||
plan.getTotalCommittedResources(start + i));
|
plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(
|
assertEquals(
|
||||||
Resource.newInstance(1024 * (alloc1[i] + alloc2[i] + i),
|
Resource.newInstance(1024 * (alloc1[i] + alloc2[i] + i),
|
||||||
alloc1[i] + alloc2[i] + i),
|
alloc1[i] + alloc2[i] + i),
|
||||||
userCons.getCapacityAtTime(start + i));
|
userCons.getCapacityAtTime(start + i));
|
||||||
|
@ -530,9 +549,9 @@ public class TestInMemoryPlan {
|
||||||
|
|
||||||
Assert.assertNull(plan.getReservationById(reservationID1));
|
Assert.assertNull(plan.getReservationById(reservationID1));
|
||||||
for (int i = 0; i < alloc1.length; i++) {
|
for (int i = 0; i < alloc1.length; i++) {
|
||||||
Assert.assertEquals(Resource.newInstance(0, 0),
|
assertEquals(Resource.newInstance(0, 0),
|
||||||
plan.getTotalCommittedResources(start + i));
|
plan.getTotalCommittedResources(start + i));
|
||||||
Assert.assertEquals(Resource.newInstance(0, 0),
|
assertEquals(Resource.newInstance(0, 0),
|
||||||
userCons.getCapacityAtTime(start + i));
|
userCons.getCapacityAtTime(start + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,16 +740,16 @@ public class TestInMemoryPlan {
|
||||||
private void doAssertions(Plan plan, ReservationAllocation rAllocation) {
|
private void doAssertions(Plan plan, ReservationAllocation rAllocation) {
|
||||||
ReservationId reservationID = rAllocation.getReservationId();
|
ReservationId reservationID = rAllocation.getReservationId();
|
||||||
Assert.assertNotNull(plan.getReservationById(reservationID));
|
Assert.assertNotNull(plan.getReservationById(reservationID));
|
||||||
Assert.assertEquals(rAllocation, plan.getReservationById(reservationID));
|
assertEquals(rAllocation, plan.getReservationById(reservationID));
|
||||||
Assert.assertTrue(((InMemoryPlan) plan).getAllReservations().size() == 1);
|
Assert.assertTrue(((InMemoryPlan) plan).getAllReservations().size() == 1);
|
||||||
if (rAllocation.getPeriodicity() <= 0) {
|
if (rAllocation.getPeriodicity() <= 0) {
|
||||||
Assert.assertEquals(rAllocation.getEndTime(), plan.getLastEndTime());
|
assertEquals(rAllocation.getEndTime(), plan.getLastEndTime());
|
||||||
}
|
}
|
||||||
Assert.assertEquals(totalCapacity, plan.getTotalCapacity());
|
assertEquals(totalCapacity, plan.getTotalCapacity());
|
||||||
Assert.assertEquals(minAlloc, plan.getMinimumAllocation());
|
assertEquals(minAlloc, plan.getMinimumAllocation());
|
||||||
Assert.assertEquals(maxAlloc, plan.getMaximumAllocation());
|
assertEquals(maxAlloc, plan.getMaximumAllocation());
|
||||||
Assert.assertEquals(resCalc, plan.getResourceCalculator());
|
assertEquals(resCalc, plan.getResourceCalculator());
|
||||||
Assert.assertEquals(planName, plan.getQueueName());
|
assertEquals(planName, plan.getQueueName());
|
||||||
Assert.assertTrue(plan.getMoveOnExpiry());
|
Assert.assertTrue(plan.getMoveOnExpiry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,14 @@ import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.jcip.annotations.NotThreadSafe;
|
||||||
|
import org.apache.hadoop.yarn.api.records.Priority;
|
||||||
import org.apache.hadoop.yarn.api.records.ReservationDefinition;
|
import org.apache.hadoop.yarn.api.records.ReservationDefinition;
|
||||||
import org.apache.hadoop.yarn.api.records.ReservationId;
|
import org.apache.hadoop.yarn.api.records.ReservationId;
|
||||||
import org.apache.hadoop.yarn.api.records.ReservationRequest;
|
import org.apache.hadoop.yarn.api.records.ReservationRequest;
|
||||||
|
@ -54,11 +57,27 @@ import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
||||||
import org.apache.hadoop.yarn.util.resource.Resources;
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class tests the {@code AlignedPlannerWithGreedy} agent.
|
||||||
|
*/
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
@NotThreadSafe
|
||||||
|
@SuppressWarnings("VisibilityModifier")
|
||||||
public class TestAlignedPlanner {
|
public class TestAlignedPlanner {
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 0)
|
||||||
|
public String recurrenceExpression;
|
||||||
|
|
||||||
|
final static String NONPERIODIC = "0";
|
||||||
|
final static String THREEHOURPERIOD = "10800000";
|
||||||
|
final static String ONEDAYPERIOD = "86400000";
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory
|
private static final Logger LOG = LoggerFactory
|
||||||
.getLogger(TestAlignedPlanner.class);
|
.getLogger(TestAlignedPlanner.class);
|
||||||
|
|
||||||
|
@ -72,6 +91,16 @@ public class TestAlignedPlanner {
|
||||||
private Resource clusterCapacity;
|
private Resource clusterCapacity;
|
||||||
private long step;
|
private long step;
|
||||||
|
|
||||||
|
|
||||||
|
@Parameterized.Parameters(name = "Testing: periodicity {0})")
|
||||||
|
public static Collection<Object[]> data() {
|
||||||
|
return Arrays.asList(new Object[][]{
|
||||||
|
{NONPERIODIC},
|
||||||
|
{THREEHOURPERIOD},
|
||||||
|
{ONEDAYPERIOD}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSingleReservationAccept() throws PlanningException {
|
public void testSingleReservationAccept() throws PlanningException {
|
||||||
|
|
||||||
|
@ -107,6 +136,9 @@ public class TestAlignedPlanner {
|
||||||
assertTrue(alloc1.toString(),
|
assertTrue(alloc1.toString(),
|
||||||
check(alloc1, 10 * step, 20 * step, 10, 2048, 2));
|
check(alloc1, 10 * step, 20 * step, 10, 2048, 2));
|
||||||
|
|
||||||
|
System.out.println("--------AFTER AGENT----------");
|
||||||
|
System.out.println(plan.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1139,9 +1171,11 @@ public class TestAlignedPlanner {
|
||||||
long deadline, ReservationRequest[] reservationRequests,
|
long deadline, ReservationRequest[] reservationRequests,
|
||||||
ReservationRequestInterpreter rType, String username) {
|
ReservationRequestInterpreter rType, String username) {
|
||||||
|
|
||||||
return ReservationDefinition.newInstance(arrival, deadline,
|
|
||||||
ReservationRequests.newInstance(Arrays.asList(reservationRequests),
|
return ReservationDefinition.newInstance(arrival,
|
||||||
rType), username);
|
deadline, ReservationRequests
|
||||||
|
.newInstance(Arrays.asList(reservationRequests), rType),
|
||||||
|
username, recurrenceExpression, Priority.UNDEFINED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,13 +59,20 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
|
@SuppressWarnings("VisibilityModifier")
|
||||||
public class TestGreedyReservationAgent {
|
public class TestGreedyReservationAgent {
|
||||||
|
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 0)
|
||||||
|
public boolean allocateLeft;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 1)
|
||||||
|
public String recurrenceExpression;
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory
|
private static final Logger LOG = LoggerFactory
|
||||||
.getLogger(TestGreedyReservationAgent.class);
|
.getLogger(TestGreedyReservationAgent.class);
|
||||||
|
|
||||||
|
@ -76,16 +83,18 @@ public class TestGreedyReservationAgent {
|
||||||
Resource maxAlloc = Resource.newInstance(1024 * 8, 8);
|
Resource maxAlloc = Resource.newInstance(1024 * 8, 8);
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
long step;
|
long step;
|
||||||
boolean allocateLeft;
|
|
||||||
|
|
||||||
public TestGreedyReservationAgent(Boolean b){
|
@Parameterized.Parameters(name = "Testing: allocateLeft {0}," +
|
||||||
this.allocateLeft = b;
|
" recurrenceExpression {1})")
|
||||||
}
|
|
||||||
|
|
||||||
@Parameters
|
|
||||||
public static Collection<Object[]> data() {
|
public static Collection<Object[]> data() {
|
||||||
return Arrays.asList(new Object[][] {
|
return Arrays.asList(new Object[][] {
|
||||||
{true}, {false}});
|
{true, "0"},
|
||||||
|
{false, "0"},
|
||||||
|
{true, "7200000"},
|
||||||
|
{false, "7200000"},
|
||||||
|
{true, "86400000"},
|
||||||
|
{false, "86400000"}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -134,6 +143,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(5 * step);
|
rr.setArrival(5 * step);
|
||||||
rr.setDeadline(20 * step);
|
rr.setDeadline(20 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
Resource.newInstance(2048, 2), 10, 5, 10 * step);
|
Resource.newInstance(2048, 2), 10, 5, 10 * step);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
|
@ -193,6 +203,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(5 * step);
|
rr.setArrival(5 * step);
|
||||||
rr.setDeadline(100 * step);
|
rr.setDeadline(100 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequest r =
|
ReservationRequest r =
|
||||||
ReservationRequest.newInstance(Resource.newInstance(2048, 2), 20, 20,
|
ReservationRequest.newInstance(Resource.newInstance(2048, 2), 20, 20,
|
||||||
10 * step);
|
10 * step);
|
||||||
|
@ -283,8 +294,9 @@ public class TestGreedyReservationAgent {
|
||||||
int[] f = { 100, 100 };
|
int[] f = { 100, 100 };
|
||||||
|
|
||||||
ReservationDefinition rDef =
|
ReservationDefinition rDef =
|
||||||
ReservationSystemTestUtil.createSimpleReservationDefinition(
|
ReservationSystemTestUtil.createSimpleReservationDefinition(30 * step,
|
||||||
30 * step, 30 * step + f.length * step, f.length * step);
|
30 * step + f.length * step, f.length * step, 1,
|
||||||
|
recurrenceExpression);
|
||||||
assertTrue(plan.toString(),
|
assertTrue(plan.toString(),
|
||||||
plan.addReservation(new InMemoryReservationAllocation(
|
plan.addReservation(new InMemoryReservationAllocation(
|
||||||
ReservationSystemTestUtil.getNewReservationId(), rDef, "u1",
|
ReservationSystemTestUtil.getNewReservationId(), rDef, "u1",
|
||||||
|
@ -296,6 +308,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(0 * step);
|
rr.setArrival(0 * step);
|
||||||
rr.setDeadline(70 * step);
|
rr.setDeadline(70 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ORDER);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ORDER);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
|
@ -346,10 +359,11 @@ public class TestGreedyReservationAgent {
|
||||||
prepareBasicPlan();
|
prepareBasicPlan();
|
||||||
// create a completely utilized segment at time 30
|
// create a completely utilized segment at time 30
|
||||||
int[] f = { 100, 100 };
|
int[] f = { 100, 100 };
|
||||||
ReservationDefinition rDef =
|
ReservationDefinition rDef = ReservationSystemTestUtil
|
||||||
ReservationSystemTestUtil.createSimpleReservationDefinition(
|
.createSimpleReservationDefinition(30, 30 * step + f.length * step,
|
||||||
30, 30 * step + f.length * step, f.length * step);
|
f.length * step, 1, recurrenceExpression);
|
||||||
assertTrue(plan.toString(),
|
assertTrue(
|
||||||
|
plan.toString(),
|
||||||
plan.addReservation(new InMemoryReservationAllocation(
|
plan.addReservation(new InMemoryReservationAllocation(
|
||||||
ReservationSystemTestUtil.getNewReservationId(), rDef, "u1",
|
ReservationSystemTestUtil.getNewReservationId(), rDef, "u1",
|
||||||
"dedicated", 30 * step, 30 * step + f.length * step,
|
"dedicated", 30 * step, 30 * step + f.length * step,
|
||||||
|
@ -406,6 +420,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(0 * step);
|
rr.setArrival(0 * step);
|
||||||
rr.setDeadline(60 * step);
|
rr.setDeadline(60 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ORDER_NO_GAP);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ORDER_NO_GAP);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
|
@ -453,6 +468,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(100 * step);
|
rr.setArrival(100 * step);
|
||||||
rr.setDeadline(120 * step);
|
rr.setDeadline(120 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ALL);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ALL);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
|
@ -494,6 +510,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(100 * step);
|
rr.setArrival(100 * step);
|
||||||
rr.setDeadline(120 * step);
|
rr.setDeadline(120 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ANY);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ANY);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
|
@ -542,6 +559,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(100L);
|
rr.setArrival(100L);
|
||||||
rr.setDeadline(120L);
|
rr.setDeadline(120L);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ANY);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ANY);
|
||||||
|
|
||||||
|
@ -587,6 +605,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(100 * step);
|
rr.setArrival(100 * step);
|
||||||
rr.setDeadline(120 * step);
|
rr.setDeadline(120 * step);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ALL);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ALL);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
|
@ -635,6 +654,7 @@ public class TestGreedyReservationAgent {
|
||||||
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
rr.setArrival(100L);
|
rr.setArrival(100L);
|
||||||
rr.setDeadline(120L);
|
rr.setDeadline(120L);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
reqs.setInterpreter(ReservationRequestInterpreter.R_ALL);
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ALL);
|
||||||
ReservationRequest r = ReservationRequest.newInstance(
|
ReservationRequest r = ReservationRequest.newInstance(
|
||||||
|
@ -759,25 +779,4 @@ public class TestGreedyReservationAgent {
|
||||||
+ " in " + (end - start) + "ms");
|
+ " in " + (end - start) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] arg) {
|
|
||||||
|
|
||||||
boolean left = false;
|
|
||||||
// run a stress test with by default 1000 random jobs
|
|
||||||
int numJobs = 1000;
|
|
||||||
if (arg.length > 0) {
|
|
||||||
numJobs = Integer.parseInt(arg[0]);
|
|
||||||
}
|
|
||||||
if (arg.length > 1) {
|
|
||||||
left = Boolean.parseBoolean(arg[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
TestGreedyReservationAgent test = new TestGreedyReservationAgent(left);
|
|
||||||
test.setup();
|
|
||||||
test.testStress(numJobs);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,213 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* 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 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.api.records.impl.pb.ReservationDefinitionPBImpl;
|
||||||
|
import org.apache.hadoop.yarn.api.records.impl.pb.ReservationRequestsPBImpl;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||||
|
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.Plan;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation;
|
||||||
|
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.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.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose ReservationAgent tester.
|
||||||
|
*/
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
@SuppressWarnings("VisibilityModifier")
|
||||||
|
public class TestReservationAgents {
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 0)
|
||||||
|
public Class agentClass;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 1)
|
||||||
|
public boolean allocateLeft;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 2)
|
||||||
|
public String recurrenceExpression;
|
||||||
|
|
||||||
|
@Parameterized.Parameter(value = 3)
|
||||||
|
public int numOfNodes;
|
||||||
|
|
||||||
|
private long step;
|
||||||
|
private Random rand = new Random(2);
|
||||||
|
private ReservationAgent agent;
|
||||||
|
private Plan plan;
|
||||||
|
private ResourceCalculator resCalc = new DefaultResourceCalculator();
|
||||||
|
private Resource minAlloc = Resource.newInstance(1024, 1);
|
||||||
|
private Resource maxAlloc = Resource.newInstance(32 * 1023, 32);
|
||||||
|
|
||||||
|
private long timeHorizon = 2 * 24 * 3600 * 1000; // 2 days
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(TestReservationAgents.class);
|
||||||
|
|
||||||
|
@Parameterized.Parameters(name = "Testing: agent {0}, allocateLeft: {1}," +
|
||||||
|
" recurrenceExpression: {2}, numNodes: {3})")
|
||||||
|
public static Collection<Object[]> data() {
|
||||||
|
return Arrays.asList(
|
||||||
|
new Object[][] {{GreedyReservationAgent.class, true, "0", 100 },
|
||||||
|
{GreedyReservationAgent.class, false, "0", 100 },
|
||||||
|
{GreedyReservationAgent.class, true, "7200000", 100 },
|
||||||
|
{GreedyReservationAgent.class, false, "7200000", 100 },
|
||||||
|
{GreedyReservationAgent.class, true, "86400000", 100 },
|
||||||
|
{GreedyReservationAgent.class, false, "86400000", 100 },
|
||||||
|
{AlignedPlannerWithGreedy.class, true, "0", 100 },
|
||||||
|
{AlignedPlannerWithGreedy.class, false, "0", 100 },
|
||||||
|
{AlignedPlannerWithGreedy.class, true, "7200000", 100 },
|
||||||
|
{AlignedPlannerWithGreedy.class, false, "7200000", 100 },
|
||||||
|
{AlignedPlannerWithGreedy.class, true, "86400000", 100 },
|
||||||
|
{AlignedPlannerWithGreedy.class, false, "86400000", 100 } });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
|
||||||
|
long seed = rand.nextLong();
|
||||||
|
rand.setSeed(seed);
|
||||||
|
LOG.info("Running with seed: " + seed);
|
||||||
|
|
||||||
|
// setting completely loose quotas
|
||||||
|
long timeWindow = 1000000L;
|
||||||
|
Resource clusterCapacity =
|
||||||
|
Resource.newInstance(numOfNodes * 1024, numOfNodes);
|
||||||
|
step = 1000L;
|
||||||
|
String reservationQ =
|
||||||
|
ReservationSystemTestUtil.getFullReservationQueueName();
|
||||||
|
|
||||||
|
float instConstraint = 100;
|
||||||
|
float avgConstraint = 100;
|
||||||
|
|
||||||
|
ReservationSchedulerConfiguration conf = ReservationSystemTestUtil
|
||||||
|
.createConf(reservationQ, timeWindow, instConstraint, avgConstraint);
|
||||||
|
CapacityOverTimePolicy policy = new CapacityOverTimePolicy();
|
||||||
|
policy.init(reservationQ, conf);
|
||||||
|
|
||||||
|
// setting conf to
|
||||||
|
conf.setBoolean(GreedyReservationAgent.FAVOR_EARLY_ALLOCATION,
|
||||||
|
allocateLeft);
|
||||||
|
agent = (ReservationAgent) agentClass.newInstance();
|
||||||
|
agent.init(conf);
|
||||||
|
|
||||||
|
QueueMetrics queueMetrics = mock(QueueMetrics.class);
|
||||||
|
RMContext context = ReservationSystemTestUtil.createMockRMContext();
|
||||||
|
|
||||||
|
plan = new InMemoryPlan(queueMetrics, policy, agent, clusterCapacity, step,
|
||||||
|
resCalc, minAlloc, maxAlloc, "dedicated", null, true, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
|
||||||
|
long period = Long.parseLong(recurrenceExpression);
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
ReservationDefinition rr = createRandomRequest(i);
|
||||||
|
if (rr != null) {
|
||||||
|
ReservationId reservationID =
|
||||||
|
ReservationSystemTestUtil.getNewReservationId();
|
||||||
|
try {
|
||||||
|
agent.createReservation(reservationID, "u1", plan, rr);
|
||||||
|
} catch (PlanningException p) {
|
||||||
|
// happens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReservationDefinition createRandomRequest(int i)
|
||||||
|
throws PlanningException {
|
||||||
|
long arrival = (long) Math.floor(rand.nextDouble() * timeHorizon);
|
||||||
|
long period = Long.parseLong(recurrenceExpression);
|
||||||
|
|
||||||
|
// min between period and rand around 30min
|
||||||
|
long duration =
|
||||||
|
(long) Math.round(Math.min(rand.nextDouble() * 3600 * 1000, period));
|
||||||
|
|
||||||
|
// min between period and rand around 5x duration
|
||||||
|
long deadline = (long) Math
|
||||||
|
.ceil(arrival + Math.min(duration * rand.nextDouble() * 10, period));
|
||||||
|
|
||||||
|
assert((deadline - arrival) <= period);
|
||||||
|
|
||||||
|
RLESparseResourceAllocation available = plan
|
||||||
|
.getAvailableResourceOverTime("u1", null, arrival, deadline, period);
|
||||||
|
NavigableMap<Long, Resource> availableMap = available.getCumulative();
|
||||||
|
|
||||||
|
// look at available space, and for each segment, use half of it with 50%
|
||||||
|
// probability
|
||||||
|
List<ReservationRequest> reservationRequests = new ArrayList<>();
|
||||||
|
for (Map.Entry<Long, Resource> e : availableMap.entrySet()) {
|
||||||
|
if (e.getValue() != null && rand.nextDouble() > 0.001) {
|
||||||
|
int numContainers = (int) Math.ceil(Resources.divide(resCalc,
|
||||||
|
plan.getTotalCapacity(), e.getValue(), minAlloc) / 2);
|
||||||
|
long tempDur =
|
||||||
|
Math.min(duration, availableMap.higherKey(e.getKey()) - e.getKey());
|
||||||
|
reservationRequests.add(ReservationRequest.newInstance(minAlloc,
|
||||||
|
numContainers, 1, tempDur));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reservationRequests.size() < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReservationDefinition rr = new ReservationDefinitionPBImpl();
|
||||||
|
rr.setArrival(arrival);
|
||||||
|
rr.setDeadline(deadline);
|
||||||
|
rr.setRecurrenceExpression(recurrenceExpression);
|
||||||
|
ReservationRequests reqs = new ReservationRequestsPBImpl();
|
||||||
|
reqs.setInterpreter(ReservationRequestInterpreter.R_ORDER);
|
||||||
|
reqs.setReservationResources(reservationRequests);
|
||||||
|
rr.setReservationRequests(reqs);
|
||||||
|
rr.setReservationName("res_" + i);
|
||||||
|
|
||||||
|
return rr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue