You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by zj...@apache.org on 2015/06/11 03:31:43 UTC

tez git commit: TEZ-1961. Remove misleading exception "No running dag" from AM logs (zjffdu)

Repository: tez
Updated Branches:
  refs/heads/master 994c74914 -> ce26b3f52


TEZ-1961. Remove misleading exception "No running dag" from AM logs (zjffdu)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/ce26b3f5
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/ce26b3f5
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/ce26b3f5

Branch: refs/heads/master
Commit: ce26b3f52761d2a48a612a7613d99b712a320204
Parents: 994c749
Author: Jeff Zhang <zj...@apache.org>
Authored: Thu Jun 11 09:31:34 2015 +0800
Committer: Jeff Zhang <zj...@apache.org>
Committed: Thu Jun 11 09:31:34 2015 +0800

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../java/org/apache/tez/client/TezClient.java   | 36 ++++++++++++++------
 .../org/apache/tez/client/TezClientUtils.java   |  2 +-
 .../apache/tez/dag/api/DagTypeConverters.java   | 18 +++++-----
 .../src/main/proto/DAGClientAMProtocol.proto    |  4 +--
 .../org/apache/tez/client/TestTezClient.java    | 15 ++++----
 .../tez/dag/api/client/DAGClientHandler.java    |  6 +---
 ...DAGClientAMProtocolBlockingPBServerImpl.java |  6 ++--
 .../org/apache/tez/dag/app/DAGAppMaster.java    |  4 ++-
 .../dag/api/client/TestDAGClientHandler.java    | 16 ++++-----
 .../org/apache/tez/mapreduce/TestMRRJobs.java   | 10 ++++--
 11 files changed, 68 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 469badc..c7c3686 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -36,6 +36,7 @@ Release 0.7.1: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-1961. Remove misleading exception "No running dag" from AM logs.
   TEZ-2546. Tez UI: Fetch hive query text from timeline if dagInfo is not set.
   TEZ-2513. Tez UI: Allow filtering by DAG ID on All dags table.
   TEZ-2541. DAGClientImpl enable TimelineClient check is wrong.

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-api/src/main/java/org/apache/tez/client/TezClient.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/client/TezClient.java b/tez-api/src/main/java/org/apache/tez/client/TezClient.java
index 8120070..aad6e76 100644
--- a/tez-api/src/main/java/org/apache/tez/client/TezClient.java
+++ b/tez-api/src/main/java/org/apache/tez/client/TezClient.java
@@ -498,7 +498,7 @@ public class TezClient {
         sessionStopped = true;
         boolean sessionShutdownSuccessful = false;
         try {
-          DAGClientAMProtocolBlockingPB proxy = getSessionAMProxy(sessionAppId);
+          DAGClientAMProtocolBlockingPB proxy = getAMProxy(sessionAppId);
           if (proxy != null) {
             ShutdownSessionRequestProto request =
                 ShutdownSessionRequestProto.newBuilder().build();
@@ -587,17 +587,14 @@ public class TezClient {
       case FINISHED:
         return TezAppMasterStatus.SHUTDOWN;
       case RUNNING:
-        if (!isSession) {
-          return TezAppMasterStatus.RUNNING;
-        }
         try {
-          DAGClientAMProtocolBlockingPB proxy = getSessionAMProxy(appId);
+          DAGClientAMProtocolBlockingPB proxy = getAMProxy(appId);
           if (proxy == null) {
             return TezAppMasterStatus.INITIALIZING;
           }
           GetAMStatusResponseProto response = proxy.getAMStatus(null,
               GetAMStatusRequestProto.newBuilder().build());
-          return DagTypeConverters.convertTezSessionStatusFromProto(
+          return DagTypeConverters.convertTezAppMasterStatusFromProto(
               response.getStatus());
         } catch (TezException e) {
           LOG.info("Failed to retrieve AM Status via proxy", e);
@@ -671,6 +668,7 @@ public class TezClient {
       // nothing to wait for in non-session mode
       return;
     }
+
     verifySessionStateForSubmission();
     while (true) {
       TezAppMasterStatus status = getAppMasterStatus();
@@ -684,7 +682,23 @@ public class TezClient {
       Thread.sleep(SLEEP_FOR_READY);
     }
   }
-  
+
+  private void waitNonSessionTillReady() throws IOException, TezException {
+    Preconditions.checkArgument(!isSession, "It is supposed to be only called in non-session mode");
+    while (true) {
+      TezAppMasterStatus status = getAppMasterStatus();
+      // DAGClient will handle the AM SHUTDOWN case
+      if (status.equals(TezAppMasterStatus.RUNNING)
+          || status.equals(TezAppMasterStatus.SHUTDOWN)) {
+        return;
+      }
+      try {
+        Thread.sleep(SLEEP_FOR_READY);
+      } catch (InterruptedException e) {
+        throw new TezException("TezClient is interrupted");
+      }
+    }
+  }
   @VisibleForTesting
   // for testing
   @Private
@@ -694,9 +708,9 @@ public class TezClient {
 
   @VisibleForTesting
   // for testing
-  protected DAGClientAMProtocolBlockingPB getSessionAMProxy(ApplicationId appId) 
+  protected DAGClientAMProtocolBlockingPB getAMProxy(ApplicationId appId)
       throws TezException, IOException {
-    return TezClientUtils.getSessionAMProxy(
+    return TezClientUtils.getAMProxy(
         frameworkClient, amConfig.getYarnConfiguration(), appId);
   }
 
@@ -706,7 +720,7 @@ public class TezClient {
     long endTime = startTime + (clientTimeout * 1000);
     DAGClientAMProtocolBlockingPB proxy = null;
     while (true) {
-      proxy = getSessionAMProxy(sessionAppId);
+      proxy = getAMProxy(sessionAppId);
       if (proxy != null) {
         break;
       }
@@ -768,6 +782,8 @@ public class TezClient {
     } catch (YarnException e) {
       throw new TezException(e);
     }
+    // wait for dag in non-session mode to start running, so that we can start to getDAGStatus
+    waitNonSessionTillReady();
     return getDAGClient(appId, amConfig.getTezConfiguration(), frameworkClient);
   }
 

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java b/tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java
index 8f5b48e..73ed7f4 100644
--- a/tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java
+++ b/tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java
@@ -827,7 +827,7 @@ public class TezClientUtils {
     return textPath;
   }
 
-  static DAGClientAMProtocolBlockingPB getSessionAMProxy(FrameworkClient yarnClient,
+  static DAGClientAMProtocolBlockingPB getAMProxy(FrameworkClient yarnClient,
       Configuration conf,
       ApplicationId applicationId) throws TezException, IOException {
     ApplicationReport appReport;

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-api/src/main/java/org/apache/tez/dag/api/DagTypeConverters.java
----------------------------------------------------------------------
diff --git a/tez-api/src/main/java/org/apache/tez/dag/api/DagTypeConverters.java b/tez-api/src/main/java/org/apache/tez/dag/api/DagTypeConverters.java
index 4dc7b38..8b1d553 100644
--- a/tez-api/src/main/java/org/apache/tez/dag/api/DagTypeConverters.java
+++ b/tez-api/src/main/java/org/apache/tez/dag/api/DagTypeConverters.java
@@ -53,7 +53,7 @@ import org.apache.tez.dag.api.EdgeProperty.DataMovementType;
 import org.apache.tez.dag.api.EdgeProperty.DataSourceType;
 import org.apache.tez.dag.api.EdgeProperty.SchedulingType;
 import org.apache.tez.dag.api.client.StatusGetOpts;
-import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.TezSessionStatusProto;
+import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.TezAppMasterStatusProto;
 import org.apache.tez.dag.api.records.DAGProtos;
 import org.apache.tez.dag.api.records.DAGProtos.ConfigurationProto;
 import org.apache.tez.dag.api.records.DAGProtos.EdgePlan;
@@ -468,8 +468,8 @@ public class DagTypeConverters {
     return pd;
   }
 
-  public static TezAppMasterStatus convertTezSessionStatusFromProto(
-      TezSessionStatusProto proto) {
+  public static TezAppMasterStatus convertTezAppMasterStatusFromProto(
+          TezAppMasterStatusProto proto) {
     switch (proto) {
     case INITIALIZING:
       return TezAppMasterStatus.INITIALIZING;
@@ -484,17 +484,17 @@ public class DagTypeConverters {
         + " proto");
   }
 
-  public static TezSessionStatusProto convertTezSessionStatusToProto(
-      TezAppMasterStatus status) {
+  public static TezAppMasterStatusProto convertTezAppMasterStatusToProto(
+    TezAppMasterStatus status) {
     switch (status) {
     case INITIALIZING:
-      return TezSessionStatusProto.INITIALIZING;
+      return TezAppMasterStatusProto.INITIALIZING;
     case READY:
-      return TezSessionStatusProto.READY;
+      return TezAppMasterStatusProto.READY;
     case RUNNING:
-      return TezSessionStatusProto.RUNNING;
+      return TezAppMasterStatusProto.RUNNING;
     case SHUTDOWN:
-      return TezSessionStatusProto.SHUTDOWN;
+      return TezAppMasterStatusProto.SHUTDOWN;
     }
     throw new TezUncheckedException("Could not convert TezSessionStatus to"
         + " proto");

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-api/src/main/proto/DAGClientAMProtocol.proto
----------------------------------------------------------------------
diff --git a/tez-api/src/main/proto/DAGClientAMProtocol.proto b/tez-api/src/main/proto/DAGClientAMProtocol.proto
index 143cded..a8171e7 100644
--- a/tez-api/src/main/proto/DAGClientAMProtocol.proto
+++ b/tez-api/src/main/proto/DAGClientAMProtocol.proto
@@ -75,7 +75,7 @@ message ShutdownSessionRequestProto {
 message ShutdownSessionResponseProto {
 }
 
-enum TezSessionStatusProto {
+enum TezAppMasterStatusProto {
   INITIALIZING = 0;
   READY = 1;
   RUNNING = 2;
@@ -86,7 +86,7 @@ message GetAMStatusRequestProto {
 }
 
 message GetAMStatusResponseProto {
-  required TezSessionStatusProto status = 1;
+  required TezAppMasterStatusProto status = 1;
 }
 
 service DAGClientAMProtocol {

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
----------------------------------------------------------------------
diff --git a/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java b/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
index 14d4d7f..dc0fbb1 100644
--- a/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
+++ b/tez-api/src/test/java/org/apache/tez/client/TestTezClient.java
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.google.protobuf.ServiceException;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.security.Credentials;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
@@ -59,7 +60,7 @@ import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.GetAMStatusReque
 import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.GetAMStatusResponseProto;
 import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.ShutdownSessionRequestProto;
 import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.SubmitDAGRequestProto;
-import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.TezSessionStatusProto;
+import org.apache.tez.dag.api.client.rpc.DAGClientAMProtocolRPC.TezAppMasterStatusProto;
 import org.hamcrest.CoreMatchers;
 import org.junit.Assert;
 import org.junit.Test;
@@ -89,20 +90,20 @@ public class TestTezClient {
     }
     
     @Override
-    protected DAGClientAMProtocolBlockingPB getSessionAMProxy(ApplicationId appId) 
+    protected DAGClientAMProtocolBlockingPB getAMProxy(ApplicationId appId)
         throws TezException, IOException {
       if (!callRealGetSessionAMProxy) {
         return sessionAmProxy;
       }
-      return super.getSessionAMProxy(appId);
+      return super.getAMProxy(appId);
     }
   }
   
-  TezClientForTest configure() throws YarnException, IOException {
+  TezClientForTest configure() throws YarnException, IOException, ServiceException {
     return configure(new HashMap<String, LocalResource>(), true);
   }
   
-  TezClientForTest configure(Map<String, LocalResource> lrs, boolean isSession) throws YarnException, IOException {
+  TezClientForTest configure(Map<String, LocalResource> lrs, boolean isSession) throws YarnException, IOException, ServiceException {
     TezConfiguration conf = new TezConfiguration();
     conf.setBoolean(TezConfiguration.TEZ_IGNORE_LIB_URIS, true);
     conf.setBoolean(TezConfiguration.TEZ_AM_SESSION_MODE, isSession);
@@ -113,6 +114,8 @@ public class TestTezClient {
     when(yarnClient.createApplication().getNewApplicationResponse().getApplicationId()).thenReturn(appId1);
 
     DAGClientAMProtocolBlockingPB sessionAmProxy = mock(DAGClientAMProtocolBlockingPB.class, RETURNS_DEEP_STUBS);
+    when(sessionAmProxy.getAMStatus(any(RpcController.class), any(GetAMStatusRequestProto.class)))
+        .thenReturn(GetAMStatusResponseProto.newBuilder().setStatus(TezAppMasterStatusProto.RUNNING).build());
 
     client.sessionAmProxy = sessionAmProxy;
     client.mockTezYarnClient = new TezYarnClient(yarnClient);
@@ -252,7 +255,7 @@ public class TestTezClient {
     
     when(
         client.sessionAmProxy.getAMStatus((RpcController) any(), (GetAMStatusRequestProto) any()))
-        .thenReturn(GetAMStatusResponseProto.newBuilder().setStatus(TezSessionStatusProto.READY).build());
+        .thenReturn(GetAMStatusResponseProto.newBuilder().setStatus(TezAppMasterStatusProto.READY).build());
 
     PreWarmVertex vertex = PreWarmVertex.create("PreWarm", 1, Resource.newInstance(1, 1));
     client.preWarm(vertex);

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-dag/src/main/java/org/apache/tez/dag/api/client/DAGClientHandler.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/client/DAGClientHandler.java b/tez-dag/src/main/java/org/apache/tez/dag/api/client/DAGClientHandler.java
index 9d35d76..e43f06f 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/client/DAGClientHandler.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/api/client/DAGClientHandler.java
@@ -125,11 +125,7 @@ public class DAGClientHandler {
     }
   }
 
-  public synchronized TezAppMasterStatus getSessionStatus() throws TezException {
-    if (!dagAppMaster.isSession()) {
-      throw new TezException("Unsupported operation as AM not running in"
-          + " session mode");
-    }
+  public synchronized TezAppMasterStatus getTezAppMasterStatus() throws TezException {
     switch (dagAppMaster.getState()) {
     case NEW:
     case INITED:

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-dag/src/main/java/org/apache/tez/dag/api/client/rpc/DAGClientAMProtocolBlockingPBServerImpl.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/api/client/rpc/DAGClientAMProtocolBlockingPBServerImpl.java b/tez-dag/src/main/java/org/apache/tez/dag/api/client/rpc/DAGClientAMProtocolBlockingPBServerImpl.java
index 4c29b79..a5f51c8 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/api/client/rpc/DAGClientAMProtocolBlockingPBServerImpl.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/api/client/rpc/DAGClientAMProtocolBlockingPBServerImpl.java
@@ -20,10 +20,8 @@ package org.apache.tez.dag.api.client.rpc;
 
 import java.io.IOException;
 import java.security.AccessControlException;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.records.LocalResource;
@@ -190,9 +188,9 @@ public class DAGClientAMProtocolBlockingPBServerImpl implements DAGClientAMProto
       throw new AccessControlException("User " + user + " cannot perform AM view operation");
     }
     try {
-      TezAppMasterStatus sessionStatus = real.getSessionStatus();
+      TezAppMasterStatus sessionStatus = real.getTezAppMasterStatus();
       return GetAMStatusResponseProto.newBuilder().setStatus(
-          DagTypeConverters.convertTezSessionStatusToProto(sessionStatus))
+          DagTypeConverters.convertTezAppMasterStatusToProto(sessionStatus))
           .build();
     } catch(TezException e) {
       throw wrapException(e);

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java b/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
index fa4c42d..4c6b285 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java
@@ -2121,7 +2121,6 @@ public class DAGAppMaster extends AbstractService {
   private void startDAG(DAGPlan dagPlan, Map<String, LocalResource> additionalAMResources)
       throws TezException {
     long submitTime = this.clock.getTime();
-    this.state = DAGAppMasterState.RUNNING;
     this.appName = dagPlan.getName();
     if (dagNames.contains(dagPlan.getName())) {
       throw new TezException("Duplicate dag name '" + dagPlan.getName() + "'");
@@ -2166,6 +2165,9 @@ public class DAGAppMaster extends AbstractService {
     }
 
     startDAGExecution(newDAG, lrDiff);
+
+    // set state after curDag is set
+    this.state = DAGAppMasterState.RUNNING;
   }
 
   private void startDAGExecution(DAG dag, final Map<String, LocalResource> additionalAmResources)

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-dag/src/test/java/org/apache/tez/dag/api/client/TestDAGClientHandler.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/api/client/TestDAGClientHandler.java b/tez-dag/src/test/java/org/apache/tez/dag/api/client/TestDAGClientHandler.java
index 6aebbc8..80414ba 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/api/client/TestDAGClientHandler.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/api/client/TestDAGClientHandler.java
@@ -58,6 +58,7 @@ public class TestDAGClientHandler {
         .thenReturn(mockVertexStatusBuilder);
 
     DAGAppMaster mockDagAM = mock(DAGAppMaster.class);
+    when(mockDagAM.getState()).thenReturn(DAGAppMasterState.RUNNING);
     AppContext mockAppContext = mock(AppContext.class);
     when(mockDagAM.getContext()).thenReturn(mockAppContext);
     when(mockDagAM.getContext().getCurrentDAG()).thenReturn(mockDAG);
@@ -91,19 +92,16 @@ public class TestDAGClientHandler {
     assertEquals(mockVertexStatusBuilder, vertexStatus);
     
     
-    // getSessionStatus
+    // getTezAppMasterStatus
     when(mockDagAM.isSession()).thenReturn(false);
-    try{
-      dagClientHandler.getSessionStatus();
-      fail("should not come here");
-    }catch(TezException e){
-      assertEquals("Unsupported operation as AM not running in session mode", e.getMessage());
-    }
+
+    assertEquals(TezAppMasterStatus.RUNNING, dagClientHandler.getTezAppMasterStatus());
+
     when(mockDagAM.isSession()).thenReturn(true);
     when(mockDagAM.getState()).thenReturn(DAGAppMasterState.INITED);
-    assertEquals(TezAppMasterStatus.INITIALIZING, dagClientHandler.getSessionStatus());
+    assertEquals(TezAppMasterStatus.INITIALIZING, dagClientHandler.getTezAppMasterStatus());
     when(mockDagAM.getState()).thenReturn(DAGAppMasterState.ERROR);
-    assertEquals(TezAppMasterStatus.SHUTDOWN, dagClientHandler.getSessionStatus());
+    assertEquals(TezAppMasterStatus.SHUTDOWN, dagClientHandler.getTezAppMasterStatus());
         
     // tryKillDAG
     try{

http://git-wip-us.apache.org/repos/asf/tez/blob/ce26b3f5/tez-tests/src/test/java/org/apache/tez/mapreduce/TestMRRJobs.java
----------------------------------------------------------------------
diff --git a/tez-tests/src/test/java/org/apache/tez/mapreduce/TestMRRJobs.java b/tez-tests/src/test/java/org/apache/tez/mapreduce/TestMRRJobs.java
index 9ab4d34..a90011c 100644
--- a/tez-tests/src/test/java/org/apache/tez/mapreduce/TestMRRJobs.java
+++ b/tez-tests/src/test/java/org/apache/tez/mapreduce/TestMRRJobs.java
@@ -131,9 +131,13 @@ public class TestMRRJobs {
     boolean succeeded = job.waitForCompletion(true);
     Assert.assertTrue(succeeded);
     Assert.assertEquals(JobStatus.State.SUCCEEDED, job.getJobState());
+    // There's one bug in YARN that there may be some suffix at the end of trackingURL (YARN-2246)
+    // After TEZ-1961, the tracking will change from http://localhost:53419/proxy/application_1430963524753_0005
+    // to http://localhost:53419/proxy/application_1430963524753_0005/ui/
+    // So here use String#contains to verify.
     Assert.assertTrue("Tracking URL was " + trackingUrl +
                       " but didn't Match Job ID " + jobId ,
-          trackingUrl.endsWith(jobId.substring(jobId.lastIndexOf("_")) + "/"));
+          trackingUrl.contains(jobId.substring(jobId.indexOf("_"))));
 
     // FIXME once counters and task progress can be obtained properly
     // TODO use dag client to test counters and task progress?
@@ -168,7 +172,7 @@ public class TestMRRJobs {
     Assert.assertEquals(JobStatus.State.SUCCEEDED, job.getJobState());
     Assert.assertTrue("Tracking URL was " + trackingUrl +
                       " but didn't Match Job ID " + jobId ,
-          trackingUrl.endsWith(jobId.substring(jobId.lastIndexOf("_")) + "/"));
+          trackingUrl.contains(jobId.substring(jobId.indexOf("_"))));
 
     // Make sure there are three files in the output-dir
 
@@ -291,7 +295,7 @@ public class TestMRRJobs {
     Assert.assertEquals(JobStatus.State.SUCCEEDED, job.getJobState());
     Assert.assertTrue("Tracking URL was " + trackingUrl +
                       " but didn't Match Job ID " + jobId ,
-          trackingUrl.endsWith(jobId.substring(jobId.lastIndexOf("_")) + "/"));
+          trackingUrl.contains(jobId.substring(jobId.indexOf("_"))));
 
     // FIXME once counters and task progress can be obtained properly
     // TODO use dag client to test counters and task progress?