YARN-5272. Handle queue names consistently in FairScheduler. (Wilfred Spiegelenburg via rchiang)

This commit is contained in:
Ray Chiang 2016-07-15 14:35:50 -07:00
parent e905a42a2c
commit f5f1c81e7d
5 changed files with 50 additions and 2 deletions

View File

@ -53,6 +53,7 @@
import org.w3c.dom.Text; import org.w3c.dom.Text;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.google.common.base.CharMatcher;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@Public @Public
@ -445,7 +446,8 @@ private void loadQueue(String parentName, Element element,
Set<String> reservableQueues, Set<String> reservableQueues,
Set<String> nonPreemptableQueues) Set<String> nonPreemptableQueues)
throws AllocationConfigurationException { throws AllocationConfigurationException {
String queueName = element.getAttribute("name").trim(); String queueName = CharMatcher.WHITESPACE.trimFrom(
element.getAttribute("name"));
if (queueName.contains(".")) { if (queueName.contains(".")) {
throw new AllocationConfigurationException("Bad fair scheduler config " throw new AllocationConfigurationException("Bad fair scheduler config "

View File

@ -37,6 +37,7 @@
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.google.common.base.CharMatcher;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
/** /**
* Maintains a list of queues as well as scheduling parameters for each queue, * Maintains a list of queues as well as scheduling parameters for each queue,
@ -457,6 +458,9 @@ public void updateAllocationConfiguration(AllocationConfiguration queueConf) {
*/ */
@VisibleForTesting @VisibleForTesting
boolean isQueueNameValid(String node) { boolean isQueueNameValid(String node) {
return !node.isEmpty() && node.equals(node.trim()); // use the same white space trim as in QueueMetrics() otherwise things fail
// guava uses a different definition for whitespace than java.
return !node.isEmpty() &&
node.equals(CharMatcher.WHITESPACE.trimFrom(node));
} }
} }

View File

@ -20,8 +20,11 @@
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
@ -580,6 +583,31 @@ public void testQueueNameContainingOnlyWhitespace() throws Exception {
allocLoader.reloadAllocations(); allocLoader.reloadAllocations();
} }
/**
* Verify that you can't have the queue name with just a non breaking
* whitespace in the allocations file.
*/
@Test (expected = AllocationConfigurationException.class)
public void testQueueNameContainingNBWhitespace() throws Exception {
Configuration conf = new Configuration();
conf.set(FairSchedulerConfiguration.ALLOCATION_FILE, ALLOC_FILE);
PrintWriter out = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(ALLOC_FILE), StandardCharsets.UTF_8));
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
out.println("<allocations>");
out.println("<queue name=\"\u00a0\">");
out.println("</queue>");
out.println("</allocations>");
out.close();
AllocationFileLoaderService allocLoader = new AllocationFileLoaderService();
allocLoader.init(conf);
ReloadListener confHolder = new ReloadListener();
allocLoader.setReloadListener(confHolder);
allocLoader.reloadAllocations();
}
/** /**
* Verify that defaultQueueSchedulingMode can't accept FIFO as a value. * Verify that defaultQueueSchedulingMode can't accept FIFO as a value.
*/ */

View File

@ -4362,6 +4362,17 @@ public void testQueueNameWithTrailingSpace() throws Exception {
assertEquals(1, scheduler.getQueueManager().getLeafQueue("B.C", true) assertEquals(1, scheduler.getQueueManager().getLeafQueue("B.C", true)
.getNumRunnableApps()); .getNumRunnableApps());
assertNotNull(scheduler.getSchedulerApp(appAttemptId3)); assertNotNull(scheduler.getSchedulerApp(appAttemptId3));
// submit app with queue name "A\u00a0" (non-breaking space)
ApplicationAttemptId appAttemptId4 = createAppAttemptId(4, 1);
AppAddedSchedulerEvent appAddedEvent4 = new AppAddedSchedulerEvent(
appAttemptId4.getApplicationId(), "A\u00a0", "user1");
scheduler.handle(appAddedEvent4);
// submission rejected
assertEquals(3, scheduler.getQueueManager().getLeafQueues().size());
assertNull(scheduler.getSchedulerApplications().get(appAttemptId4.
getApplicationId()));
assertNull(scheduler.getSchedulerApp(appAttemptId4));
} }
@Test @Test

View File

@ -131,6 +131,9 @@ public void testCheckQueueNodeName() {
assertFalse(queueManager.isQueueNameValid(" a")); assertFalse(queueManager.isQueueNameValid(" a"));
assertFalse(queueManager.isQueueNameValid("a ")); assertFalse(queueManager.isQueueNameValid("a "));
assertFalse(queueManager.isQueueNameValid(" a ")); assertFalse(queueManager.isQueueNameValid(" a "));
assertFalse(queueManager.isQueueNameValid("\u00a0"));
assertFalse(queueManager.isQueueNameValid("a\u00a0"));
assertFalse(queueManager.isQueueNameValid("\u00a0a\u00a0"));
assertTrue(queueManager.isQueueNameValid("a b")); assertTrue(queueManager.isQueueNameValid("a b"));
assertTrue(queueManager.isQueueNameValid("a")); assertTrue(queueManager.isQueueNameValid("a"));
} }