/******************************************************************************* * 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; import java.util.Collections; import java.util.HashMap; import java.util.Map; 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.api.records.impl.pb.ReservationDefinitionPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.ReservationRequestsPBImpl; import org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator; import org.apache.hadoop.yarn.util.resource.ResourceCalculator; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestInMemoryReservationAllocation { private String user = "yarn"; private String planName = "test-reservation"; private ResourceCalculator resCalc; private Resource minAlloc; private Random rand = new Random(); @Before public void setUp() { resCalc = new DefaultResourceCalculator(); minAlloc = Resource.newInstance(1, 1); } @After public void tearDown() { user = null; planName = null; resCalc = null; minAlloc = null; } @Test public void testBlocks() { ReservationId reservationID = ReservationId.newInstance(rand.nextLong(), rand.nextLong()); int[] alloc = { 10, 10, 10, 10, 10, 10 }; int start = 100; ReservationDefinition rDef = createSimpleReservationDefinition(start, start + alloc.length + 1, alloc.length); Map<ReservationInterval, ReservationRequest> allocations = generateAllocation(start, alloc, false, false); ReservationAllocation rAllocation = new InMemoryReservationAllocation(reservationID, rDef, user, planName, start, start + alloc.length + 1, allocations, resCalc, minAlloc); doAssertions(rAllocation, reservationID, rDef, allocations, start, alloc); Assert.assertFalse(rAllocation.containsGangs()); for (int i = 0; i < alloc.length; i++) { Assert.assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])), rAllocation.getResourcesAtTime(start + i)); } } @Test public void testSteps() { ReservationId reservationID = ReservationId.newInstance(rand.nextLong(), rand.nextLong()); int[] alloc = { 10, 10, 10, 10, 10, 10 }; int start = 100; ReservationDefinition rDef = createSimpleReservationDefinition(start, start + alloc.length + 1, alloc.length); Map<ReservationInterval, ReservationRequest> allocations = generateAllocation(start, alloc, true, false); ReservationAllocation rAllocation = new InMemoryReservationAllocation(reservationID, rDef, user, planName, start, start + alloc.length + 1, allocations, resCalc, minAlloc); doAssertions(rAllocation, reservationID, rDef, allocations, start, alloc); Assert.assertFalse(rAllocation.containsGangs()); for (int i = 0; i < alloc.length; i++) { Assert.assertEquals( Resource.newInstance(1024 * (alloc[i] + i), (alloc[i] + i)), rAllocation.getResourcesAtTime(start + i)); } } @Test public void testSkyline() { ReservationId reservationID = ReservationId.newInstance(rand.nextLong(), rand.nextLong()); int[] alloc = { 0, 5, 10, 10, 5, 0 }; int start = 100; ReservationDefinition rDef = createSimpleReservationDefinition(start, start + alloc.length + 1, alloc.length); Map<ReservationInterval, ReservationRequest> allocations = generateAllocation(start, alloc, true, false); ReservationAllocation rAllocation = new InMemoryReservationAllocation(reservationID, rDef, user, planName, start, start + alloc.length + 1, allocations, resCalc, minAlloc); doAssertions(rAllocation, reservationID, rDef, allocations, start, alloc); Assert.assertFalse(rAllocation.containsGangs()); for (int i = 0; i < alloc.length; i++) { Assert.assertEquals( Resource.newInstance(1024 * (alloc[i] + i), (alloc[i] + i)), rAllocation.getResourcesAtTime(start + i)); } } @Test public void testZeroAlloaction() { ReservationId reservationID = ReservationId.newInstance(rand.nextLong(), rand.nextLong()); int[] alloc = {}; long start = 0; ReservationDefinition rDef = createSimpleReservationDefinition(start, start + alloc.length + 1, alloc.length); Map<ReservationInterval, ReservationRequest> allocations = new HashMap<ReservationInterval, ReservationRequest>(); ReservationAllocation rAllocation = new InMemoryReservationAllocation(reservationID, rDef, user, planName, start, start + alloc.length + 1, allocations, resCalc, minAlloc); doAssertions(rAllocation, reservationID, rDef, allocations, (int) start, alloc); Assert.assertFalse(rAllocation.containsGangs()); } @Test public void testGangAlloaction() { ReservationId reservationID = ReservationId.newInstance(rand.nextLong(), rand.nextLong()); int[] alloc = { 10, 10, 10, 10, 10, 10 }; int start = 100; ReservationDefinition rDef = createSimpleReservationDefinition(start, start + alloc.length + 1, alloc.length); Map<ReservationInterval, ReservationRequest> allocations = generateAllocation(start, alloc, false, true); ReservationAllocation rAllocation = new InMemoryReservationAllocation(reservationID, rDef, user, planName, start, start + alloc.length + 1, allocations, resCalc, minAlloc); doAssertions(rAllocation, reservationID, rDef, allocations, start, alloc); Assert.assertTrue(rAllocation.containsGangs()); for (int i = 0; i < alloc.length; i++) { Assert.assertEquals(Resource.newInstance(1024 * (alloc[i]), (alloc[i])), rAllocation.getResourcesAtTime(start + i)); } } private void doAssertions(ReservationAllocation rAllocation, ReservationId reservationID, ReservationDefinition rDef, Map<ReservationInterval, ReservationRequest> allocations, int start, int[] alloc) { Assert.assertEquals(reservationID, rAllocation.getReservationId()); Assert.assertEquals(rDef, rAllocation.getReservationDefinition()); Assert.assertEquals(allocations, rAllocation.getAllocationRequests()); Assert.assertEquals(user, rAllocation.getUser()); Assert.assertEquals(planName, rAllocation.getPlanName()); Assert.assertEquals(start, rAllocation.getStartTime()); Assert.assertEquals(start + alloc.length + 1, rAllocation.getEndTime()); } private ReservationDefinition createSimpleReservationDefinition(long arrival, long deadline, long duration) { // create a request with a single atomic ask ReservationRequest r = ReservationRequest.newInstance(Resource.newInstance(1024, 1), 1, 1, duration); ReservationDefinition rDef = new ReservationDefinitionPBImpl(); ReservationRequests reqs = new ReservationRequestsPBImpl(); reqs.setReservationResources(Collections.singletonList(r)); reqs.setInterpreter(ReservationRequestInterpreter.R_ALL); rDef.setReservationRequests(reqs); rDef.setArrival(arrival); rDef.setDeadline(deadline); return rDef; } private Map<ReservationInterval, ReservationRequest> generateAllocation( int startTime, int[] alloc, boolean isStep, boolean isGang) { Map<ReservationInterval, ReservationRequest> req = new HashMap<ReservationInterval, ReservationRequest>(); int numContainers = 0; for (int i = 0; i < alloc.length; i++) { if (isStep) { numContainers = alloc[i] + i; } else { numContainers = alloc[i]; } ReservationRequest rr = ReservationRequest.newInstance(Resource.newInstance(1024, 1), (numContainers)); if (isGang) { rr.setConcurrency(numContainers); } req.put(new ReservationInterval(startTime + i, startTime + i + 1), rr); } return req; } }