From 804f86f42cc0462164d2bfd8d42a2e6ebb1e8c13 Mon Sep 17 00:00:00 2001 From: Jason Darrell Lowe Date: Wed, 12 Mar 2014 21:59:50 +0000 Subject: [PATCH] svn merge -c 1576940 FIXES: MAPREDUCE-5778. JobSummary does not escape newlines in the job name. Contributed by Akira AJISAKA git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1576943 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-mapreduce-project/CHANGES.txt | 3 + .../mapreduce/jobhistory/JobSummary.java | 6 +- .../mapreduce/jobhistory/TestJobSummary.java | 68 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/jobhistory/TestJobSummary.java diff --git a/hadoop-mapreduce-project/CHANGES.txt b/hadoop-mapreduce-project/CHANGES.txt index 37438f86f82..a013c818251 100644 --- a/hadoop-mapreduce-project/CHANGES.txt +++ b/hadoop-mapreduce-project/CHANGES.txt @@ -72,6 +72,9 @@ Release 2.4.0 - UNRELEASED MAPREDUCE-5028. Fixed a bug in MapTask that was causing mappers to fail when a large value of io.sort.mb is set. (Karthik Kambatla via vinodkv) + MAPREDUCE-5778. JobSummary does not escape newlines in the job name (Akira + AJISAKA via jlowe) + Release 2.3.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/jobhistory/JobSummary.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/jobhistory/JobSummary.java index 5adfed15a9c..abe95185ffb 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/jobhistory/JobSummary.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/jobhistory/JobSummary.java @@ -228,8 +228,10 @@ public class JobSummary { } SummaryBuilder add(String key, T value) { - return _add(key, StringUtils.escapeString(String.valueOf(value), - StringUtils.ESCAPE_CHAR, charsToEscape)); + String escapedString = StringUtils.escapeString(String.valueOf(value), + StringUtils.ESCAPE_CHAR, charsToEscape).replaceAll("\n", "\\\\n") + .replaceAll("\r", "\\\\r"); + return _add(key, escapedString); } SummaryBuilder add(SummaryBuilder summary) { diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/jobhistory/TestJobSummary.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/jobhistory/TestJobSummary.java new file mode 100644 index 00000000000..31d00d942b5 --- /dev/null +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/jobhistory/TestJobSummary.java @@ -0,0 +1,68 @@ +/** + * 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.mapreduce.jobhistory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.mapreduce.v2.api.records.JobId; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class TestJobSummary { + + private static final Log LOG = LogFactory.getLog(TestJobSummary.class); + private JobSummary summary = new JobSummary(); + + @Before + public void before() { + JobId mockJobId = mock(JobId.class); + when(mockJobId.toString()).thenReturn("testJobId"); + summary.setJobId(mockJobId); + summary.setJobSubmitTime(2); + summary.setJobLaunchTime(3); + summary.setFirstMapTaskLaunchTime(4); + summary.setFirstReduceTaskLaunchTime(5); + summary.setJobFinishTime(6); + summary.setNumFinishedMaps(1); + summary.setNumFailedMaps(0); + summary.setNumFinishedReduces(1); + summary.setNumFailedReduces(0); + summary.setUser("testUser"); + summary.setQueue("testQueue"); + summary.setJobStatus("testJobStatus"); + summary.setMapSlotSeconds(7); + summary.setReduceSlotSeconds(8); + summary.setJobName("testName"); + } + + @Test + public void testEscapeJobSummary() { + // verify newlines are escaped + summary.setJobName("aa\rbb\ncc\r\ndd"); + String out = summary.getJobSummaryString(); + LOG.info("summary: " + out); + Assert.assertFalse(out.contains("\r")); + Assert.assertFalse(out.contains("\n")); + Assert.assertTrue(out.contains("aa\\rbb\\ncc\\r\\ndd")); + } +}