@Test
public void testJobNameWithMultibyteChars() throws IOException {

  JobIndexInfo info = new JobIndexInfo();
  JobID oldJobId = JobID.forName(JOB_ID);
  JobId jobId = TypeConverter.toYarn(oldJobId);
  info.setJobId(jobId);
  info.setSubmitTime(Long.parseLong(SUBMIT_TIME));
  info.setUser(USER_NAME);
  StringBuilder sb = new StringBuilder();
  info.setFinishTime(Long.parseLong(FINISH_TIME));
  info.setNumMaps(Integer.parseInt(NUM_MAPS));
  info.setNumReduces(Integer.parseInt(NUM_REDUCES));
  info.setJobStatus(JOB_STATUS);
  info.setQueueName(QUEUE_NAME);
  info.setJobStartTime(Long.parseLong(JOB_START_TIME));
  // Test for 1 byte UTF-8 character
  // which is encoded into 1 x 3 = 3 characters by URL encode.
  for (int i = 0; i < 100; i++) {
    sb.append('%');
  }
  String longJobName = sb.toString();
  info.setJobName(longJobName);
  String jobHistoryFile =
      FileNameIndexUtils.getDoneFileName(info, 50);
  Assert.assertTrue(jobHistoryFile.length() <= 255);
  String trimedJobName = jobHistoryFile.split(
      FileNameIndexUtils.DELIMITER)[3]; // 3 is index of job name
  // 3 x 16 < 50 < 3 x 17 so the length of trimedJobName should be 48
  Assert.assertEquals(48, trimedJobName.getBytes(UTF_8).length);
  // validate whether trimmedJobName by testing reversibility
  byte[] trimedJobNameInByte = trimedJobName.getBytes(UTF_8);
  String reEncodedTrimedJobName = new String(trimedJobNameInByte, UTF_8);
  Assert.assertArrayEquals(trimedJobNameInByte,
      reEncodedTrimedJobName.getBytes(UTF_8));
  sb.setLength(0);
  // Test for 2 bytes UTF-8 character
  // which is encoded into 2 x 3 = 6 characters by URL encode.
  for (int i = 0; i < 100; i++) {
    sb.append('\u03A9'); // large omega
  }
  longJobName = sb.toString();
  info.setJobName(longJobName);
  jobHistoryFile =
      FileNameIndexUtils.getDoneFileName(info, 27);
  Assert.assertTrue(jobHistoryFile.length() <= 255);
  trimedJobName = jobHistoryFile.split(
      FileNameIndexUtils.DELIMITER)[3]; // 3 is index of job name
  // 6 x 4 < 27 < 6 x 5 so the length of trimedJobName should be 24
  Assert.assertEquals(24, trimedJobName.getBytes(UTF_8).length);
  // validate whether trimmedJobName by testing reversibility
  trimedJobNameInByte = trimedJobName.getBytes(UTF_8);
  reEncodedTrimedJobName = new String(trimedJobNameInByte, UTF_8);
  Assert.assertArrayEquals(trimedJobNameInByte,
      reEncodedTrimedJobName.getBytes(UTF_8));
  sb.setLength(0);
  // Test for 3 bytes UTF-8 character
  // which is encoded into 3 x 3 = 9 characters by URL encode.
  for (int i = 0; i < 100; i++) {
    sb.append('\u2192'); // rightwards arrow
  }
  longJobName = sb.toString();
  info.setJobName(longJobName);
  jobHistoryFile =
      FileNameIndexUtils.getDoneFileName(info, 40);
  Assert.assertTrue(jobHistoryFile.length() <= 255);
  trimedJobName = jobHistoryFile.split(
      FileNameIndexUtils.DELIMITER)[3]; // 3 is index of job name
  // 9 x 4 < 40 < 9 x 5 so the length of trimedJobName should be 36
  Assert.assertEquals(36, trimedJobName.getBytes(UTF_8).length);
  // validate whether trimmedJobName by testing reversibility
  trimedJobNameInByte = trimedJobName.getBytes(UTF_8);
  reEncodedTrimedJobName = new String(trimedJobNameInByte, UTF_8);
  Assert.assertArrayEquals(trimedJobNameInByte,
      reEncodedTrimedJobName.getBytes(UTF_8));
  sb.setLength(0);
  // Test for 4 bytes UTF-8 character
  // which is encoded into 4 x 3 = 12 characters by URL encode.
  for (int i = 0; i < 100; i++) {
    sb.append("\uD867\uDE3D"); // Mugil cephalus in Kanji.
  }
  longJobName = sb.toString();
  info.setJobName(longJobName);
  jobHistoryFile =
      FileNameIndexUtils.getDoneFileName(info, 49);
  Assert.assertTrue(jobHistoryFile.length() <= 255);
  trimedJobName = jobHistoryFile.split(
      FileNameIndexUtils.DELIMITER)[3]; // 3 is index of job name
  // 12 x 4 < 49 < 12 x 5 so the length of trimedJobName should be 48
  Assert.assertEquals(48, trimedJobName.getBytes(UTF_8).length);
  // validate whether trimmedJobName by testing reversibility
  trimedJobNameInByte = trimedJobName.getBytes(UTF_8);
  reEncodedTrimedJobName = new String(trimedJobNameInByte, UTF_8);
  Assert.assertArrayEquals(trimedJobNameInByte,
      reEncodedTrimedJobName.getBytes(UTF_8));
  sb.setLength(0);
  // Test for the combination of 1 to 4 bytes UTF-8 characters
  sb.append('\u732B') // cat in Kanji (encoded into 3 bytes x 3 characters)
    .append("[") // (encoded into 1 byte x 3 characters)
    .append('\u03BB') // small lambda (encoded into 2 bytes x 3 characters)
    .append('/') // (encoded into 1 byte x 3 characters)
    .append('A') // not url-encoded (1 byte x 1 character)
    .append("\ud867\ude49") // flying fish in
                            // Kanji (encoded into 4 bytes x 3 characters)
    .append('\u72AC'); // dog in Kanji (encoded into 3 bytes x 3 characters)
  longJobName = sb.toString();
  info.setJobName(longJobName);
  jobHistoryFile =
      FileNameIndexUtils.getDoneFileName(info, 23);
  Assert.assertTrue(jobHistoryFile.length() <= 255);
  trimedJobName = jobHistoryFile.split(
      FileNameIndexUtils.DELIMITER)[3]; // 3 is index of job name
  // total size of the first 5 characters = 22
  // 23 < total size of the first 6 characters
  Assert.assertEquals(22, trimedJobName.getBytes(UTF_8).length);
  // validate whether trimmedJobName by testing reversibility
  trimedJobNameInByte = trimedJobName.getBytes(UTF_8);
  reEncodedTrimedJobName = new String(trimedJobNameInByte, UTF_8);
  Assert.assertArrayEquals(trimedJobNameInByte,
      reEncodedTrimedJobName.getBytes(UTF_8));
}