You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ji...@apache.org on 2016/11/23 03:40:28 UTC

incubator-eagle git commit: [EAGLE-786] Add unit test for eagle-jpm-mr-running's MRRunningJobFetc…

Repository: incubator-eagle
Updated Branches:
  refs/heads/master a39ca45cb -> 7499be694


[EAGLE-786] Add unit test for eagle-jpm-mr-running's MRRunningJobFetc\u2026

 - Add unit test for eagle-jpm-mr-running's MRRunningJobFetchSpout

https://issues.apache.org/jira/browse/EAGLE-786

Author: r7raul1984 <ta...@yhd.com>

Closes #668 from r7raul1984/EAGLE-786.


Project: http://git-wip-us.apache.org/repos/asf/incubator-eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-eagle/commit/7499be69
Tree: http://git-wip-us.apache.org/repos/asf/incubator-eagle/tree/7499be69
Diff: http://git-wip-us.apache.org/repos/asf/incubator-eagle/diff/7499be69

Branch: refs/heads/master
Commit: 7499be694a6ae2c334751d49927cc5eaac6f5f2b
Parents: a39ca45
Author: r7raul1984 <ta...@yhd.com>
Authored: Wed Nov 23 11:40:19 2016 +0800
Committer: wujinhu <wu...@126.com>
Committed: Wed Nov 23 11:40:19 2016 +0800

----------------------------------------------------------------------
 eagle-jpm/eagle-jpm-mr-running/pom.xml          |  12 ++
 .../running/storm/MRRunningJobFetchSpout.java   |  64 ++++----
 .../mr/running/MRRunningJobApplicationTest.java | 147 ++++++++++++++++++-
 .../application_1479206441898_35341.json        |  35 +++++
 .../test/resources/previousmrrunningapp.json    |  64 ++++++++
 .../test/resources/thistimemrrunningapp.json    |  35 +++++
 6 files changed, 326 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/7499be69/eagle-jpm/eagle-jpm-mr-running/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-mr-running/pom.xml b/eagle-jpm/eagle-jpm-mr-running/pom.xml
index bb0ac5a..b4db22b 100644
--- a/eagle-jpm/eagle-jpm-mr-running/pom.xml
+++ b/eagle-jpm/eagle-jpm-mr-running/pom.xml
@@ -69,6 +69,18 @@
             <artifactId>eagle-app-base</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <version>${powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <version>${powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <resources>

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/7499be69/eagle-jpm/eagle-jpm-mr-running/src/main/java/org/apache/eagle/jpm/mr/running/storm/MRRunningJobFetchSpout.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-mr-running/src/main/java/org/apache/eagle/jpm/mr/running/storm/MRRunningJobFetchSpout.java b/eagle-jpm/eagle-jpm-mr-running/src/main/java/org/apache/eagle/jpm/mr/running/storm/MRRunningJobFetchSpout.java
index 7c910e7..cc5df84 100644
--- a/eagle-jpm/eagle-jpm-mr-running/src/main/java/org/apache/eagle/jpm/mr/running/storm/MRRunningJobFetchSpout.java
+++ b/eagle-jpm/eagle-jpm-mr-running/src/main/java/org/apache/eagle/jpm/mr/running/storm/MRRunningJobFetchSpout.java
@@ -18,6 +18,7 @@
 
 package org.apache.eagle.jpm.mr.running.storm;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.eagle.jpm.mr.running.MRRunningJobConfig;
 import org.apache.eagle.jpm.mr.running.recover.MRRunningJobManager;
 import org.apache.eagle.jpm.mr.runningentity.JobExecutionAPIEntity;
@@ -87,40 +88,31 @@ public class MRRunningJobFetchSpout extends BaseRichSpout {
             } else {
                 apps = resourceFetcher.getResource(Constants.ResourceType.RUNNING_MR_JOB);
                 LOG.info("get {} apps from resource manager", apps.size());
-                Set<String> running = new HashSet<>();
-                for (AppInfo appInfo : apps) {
-                    running.add(appInfo.getId());
-                }
-                Iterator<String> appIdIterator = this.runningYarnApps.iterator();
-                while (appIdIterator.hasNext()) {
-                    String appId = appIdIterator.next();
-                    boolean hasFinished = true;
-                    for (AppInfo appInfo : apps) {
-                        if (appId.equals(appInfo.getId())) {
-                            hasFinished = false;
-                        }
-                    }
 
-                    if (hasFinished) {
-                        try {
-                            Map<String, JobExecutionAPIEntity> result = this.runningJobManager.recoverYarnApp(appId);
-                            if (result.size() > 0) {
-                                if (mrApps == null) {
-                                    mrApps = new HashMap<>();
-                                }
-                                mrApps.put(appId, result);
-                                AppInfo appInfo = result.get(result.keySet().iterator().next()).getAppInfo();
-                                appInfo.setState(Constants.AppState.FINISHED.toString());
-                                apps.add(appInfo);
+                Set<String> runningAppIdsAtThisTime = runningAppIdsAtThisTime(apps);
+                Set<String> runningAppIdsAtPreviousTime = this.runningYarnApps;
+                Set<String> finishedAppIds = getFinishedAppIds(runningAppIdsAtThisTime, runningAppIdsAtPreviousTime);
+
+                Iterator<String> finishedAppIdIterator = finishedAppIds.iterator();
+                while (finishedAppIdIterator.hasNext()) {
+                    String appId = finishedAppIdIterator.next();
+                    try {
+                        Map<String, JobExecutionAPIEntity> result = this.runningJobManager.recoverYarnApp(appId);
+                        if (result.size() > 0) {
+                            if (mrApps == null) {
+                                mrApps = new HashMap<>();
                             }
-                        } catch (KeeperException.NoNodeException e) {
-                            LOG.warn("{}", e);
-                            LOG.warn("yarn app {} has finished", appId);
+                            mrApps.put(appId, result);
+                            AppInfo appInfo = result.get(result.keySet().iterator().next()).getAppInfo();
+                            appInfo.setState(Constants.AppState.FINISHED.toString());
+                            apps.add(appInfo);
                         }
+                    } catch (KeeperException.NoNodeException e) {
+                        LOG.warn("{}", e);
+                        LOG.warn("yarn app {} has finished", appId);
                     }
                 }
-
-                this.runningYarnApps = running;
+                this.runningYarnApps = runningAppIdsAtThisTime;
                 LOG.info("get {} total apps(contains finished)", apps.size());
             }
 
@@ -141,6 +133,20 @@ public class MRRunningJobFetchSpout extends BaseRichSpout {
         }
     }
 
+
+    private Set<String> getFinishedAppIds(Set<String> runningAppIdsAtThisTime, Set<String> runningAppIdsAtPreviousTime) {
+        Set<String> finishedAppIds = new HashSet<>(CollectionUtils.subtract(runningAppIdsAtPreviousTime, runningAppIdsAtThisTime));
+        return finishedAppIds;
+    }
+
+    private Set<String> runningAppIdsAtThisTime(List<AppInfo> apps) {
+        Set<String> running = new HashSet<>();
+        for (AppInfo appInfo : apps) {
+            running.add(appInfo.getId());
+        }
+        return running;
+    }
+
     private Map<String, Map<String, JobExecutionAPIEntity>> recoverRunningApps() {
         //we need read from zookeeper, path looks like /apps/mr/running/yarnAppId/jobId/
         //content of path /apps/mr/running/yarnAppId/jobId is JobExecutionAPIEntity

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/7499be69/eagle-jpm/eagle-jpm-mr-running/src/test/java/org/apache/eagle/jpm/mr/running/MRRunningJobApplicationTest.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-mr-running/src/test/java/org/apache/eagle/jpm/mr/running/MRRunningJobApplicationTest.java b/eagle-jpm/eagle-jpm-mr-running/src/test/java/org/apache/eagle/jpm/mr/running/MRRunningJobApplicationTest.java
index 3ec9089..8707182 100644
--- a/eagle-jpm/eagle-jpm-mr-running/src/test/java/org/apache/eagle/jpm/mr/running/MRRunningJobApplicationTest.java
+++ b/eagle-jpm/eagle-jpm-mr-running/src/test/java/org/apache/eagle/jpm/mr/running/MRRunningJobApplicationTest.java
@@ -16,12 +16,155 @@
  */
 package org.apache.eagle.jpm.mr.running;
 
+import backtype.storm.spout.ISpoutOutputCollector;
+import backtype.storm.spout.SpoutOutputCollector;
 import com.typesafe.config.ConfigFactory;
+import org.apache.eagle.jpm.mr.running.recover.MRRunningJobManager;
+import org.apache.eagle.jpm.mr.running.storm.MRRunningJobFetchSpout;
+import org.apache.eagle.jpm.mr.runningentity.JobExecutionAPIEntity;
+import org.apache.eagle.jpm.util.Constants;
+import org.apache.eagle.jpm.util.resourcefetch.connection.InputStreamUtils;
+import org.apache.eagle.jpm.util.resourcefetch.model.AppInfo;
+import org.apache.eagle.jpm.util.resourcefetch.model.AppsWrapper;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
 
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.*;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({InputStreamUtils.class, MRRunningJobFetchSpout.class})
+@PowerMockIgnore({"javax.*"})
 public class MRRunningJobApplicationTest {
+
+    public static final String RM_URL = "http://sandbox.hortonworks.com:50030/ws/v1/cluster/apps?applicationTypes=MAPREDUCE&state=RUNNING&anonymous=true";
+    public static final String RUNNING_YARNAPPS = "[application_1479206441898_35341, application_1479206441898_30784]";
+    public static final String TUPLE_1 = "[application_1479206441898_30784, AppInfo{id='application_1479206441898_30784', user='xxx', name='oozie:launcher:T=shell:W=wf_co_xxx_xxx_v3:A=extract_org_data:ID=0002383-161115184801730-oozie-oozi-W', queue='xxx', state='RUNNING', finalStatus='UNDEFINED', progress=95.0, trackingUI='ApplicationMaster', trackingUrl='http://host.domain.com:8088/proxy/application_1479206441898_30784/', diagnostics='', clusterId='1479206441898', applicationType='MAPREDUCE', startedTime=1479328221694, finishedTime=0, elapsedTime=13367402, amContainerLogs='http://host.domain.com:8088/node/containerlogs/container_e11_1479206441898_30784_01_000001/xxx', amHostHttpAddress='host.domain.com:8088', allocatedMB=3072, allocatedVCores=2, runningContainers=2}, null]";
+    public static final String TUPLE_2 = "[application_1479206441898_35341, AppInfo{id='application_1479206441898_35341', user='yyy', name='insert overwrite table inter...a.xxx(Stage-3)', queue='yyy', state='RUNNING', finalStatus='UNDEFINED', progress=59.545456, trackingUI='ApplicationMaster', trackingUrl='http://host.domain.com:8088/proxy/application_1479206441898_35341/', diagnostics='', clusterId='1479206441898', applicationType='MAPREDUCE', startedTime=1479341511477, finishedTime=0, elapsedTime=77619, amContainerLogs='http://host.domain.com:8042/node/containerlogs/container_e11_1479206441898_35341_01_000005/yyy', amHostHttpAddress='host.domain.com:8042', allocatedMB=27648, allocatedVCores=6, runningContainers=6}, null]";
+
+    private static final ObjectMapper OBJ_MAPPER = new ObjectMapper();
+
+    static {
+        OBJ_MAPPER.configure(JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS, true);
+    }
+
     @Test
-    public void testRunApplicationWithCLI(){
-        new MRRunningJobApplication().run(ConfigFactory.load());
+    public void testMRRunningJobFetchSpout() throws Exception {
+
+        List<Object> tuples = new ArrayList<>();
+        SpoutOutputCollector collector = new SpoutOutputCollector(new ISpoutOutputCollector() {
+            @Override
+            public List<Integer> emit(String streamId, List<Object> tuple, Object messageId) {
+                tuples.add(tuple);
+                return null;
+            }
+
+            @Override
+            public void emitDirect(int taskId, String streamId, List<Object> tuple, Object messageId) {
+
+            }
+
+            @Override
+            public void reportError(Throwable error) {
+
+            }
+        });
+
+        //1st run
+        Field initField = MRRunningJobFetchSpout.class.getDeclaredField("init");
+        initField.setAccessible(true);
+        MRRunningJobFetchSpout mrRunningJobFetchSpout = makeMrRunningJobFetchSpout();
+        boolean init = (boolean) initField.get(mrRunningJobFetchSpout);
+        mrRunningJobFetchSpout.open(new HashMap<>(), null, collector);
+        Assert.assertFalse(init);
+        mrRunningJobFetchSpout.nextTuple();
+
+        init = (boolean) initField.get(mrRunningJobFetchSpout);
+        Field runningYarnAppsField = MRRunningJobFetchSpout.class.getDeclaredField("runningYarnApps");
+        runningYarnAppsField.setAccessible(true);
+        Set<String> runningYarnApps = (Set<String>) runningYarnAppsField.get(mrRunningJobFetchSpout);
+        Assert.assertTrue(tuples.isEmpty());
+        Assert.assertTrue(init);
+        Assert.assertTrue(runningYarnApps.isEmpty());
+
+        //2nd run
+        mrRunningJobFetchSpout.nextTuple();
+
+        init = (boolean) initField.get(mrRunningJobFetchSpout);
+        Assert.assertTrue(init);
+        Assert.assertEquals(2, tuples.size());
+        Assert.assertEquals(TUPLE_1, tuples.get(0).toString());
+        Assert.assertEquals(TUPLE_2, tuples.get(1).toString());
+        runningYarnApps = (Set<String>) runningYarnAppsField.get(mrRunningJobFetchSpout);
+        Assert.assertEquals(2, runningYarnApps.size());
+        Assert.assertEquals(RUNNING_YARNAPPS, runningYarnApps.toString());
+
+        //3rd run
+        mockInputSteam("/previousmrrunningapp.json");
+        tuples.clear();
+
+        mrRunningJobFetchSpout.nextTuple();
+
+        Assert.assertTrue(init);
+        Assert.assertEquals(2, tuples.size());
+        Assert.assertEquals(TUPLE_1, tuples.get(0).toString());
+        Assert.assertEquals(TUPLE_2, tuples.get(1).toString());
+        runningYarnApps = (Set<String>) runningYarnAppsField.get(mrRunningJobFetchSpout);
+        Assert.assertEquals(2, runningYarnApps.size());
+        Assert.assertEquals(RUNNING_YARNAPPS, runningYarnApps.toString());
+
+        //4th run
+        mockInputSteam("/thistimemrrunningapp.json");
+        tuples.clear();
+
+        mrRunningJobFetchSpout.nextTuple();
+
+        Assert.assertTrue(init);
+        Assert.assertEquals(2, tuples.size());
+        Assert.assertEquals(TUPLE_1, tuples.get(0).toString());
+        Assert.assertEquals("[application_1479206441898_35341, AppInfo{id='application_1479206441898_35341', user='yyy', name='insert overwrite table inter...a.xxx(Stage-3)', queue='yyy', state='FINISHED', finalStatus='UNDEFINED', progress=59.545456, trackingUI='ApplicationMaster', trackingUrl='http://host.domain.com:8088/proxy/application_1479206441898_35341/', diagnostics='', clusterId='1479206441898', applicationType='MAPREDUCE', startedTime=1479341511477, finishedTime=0, elapsedTime=77619, amContainerLogs='http://host.domain.com:8042/node/containerlogs/container_e11_1479206441898_35341_01_000005/yyy', amHostHttpAddress='host.domain.com:8042', allocatedMB=27648, allocatedVCores=6, runningContainers=6}, {jobId=prefix:null, timestamp:0, humanReadableDate:1970-01-01 00:00:00,000, tags: , encodedRowkey:null}]", tuples.get(1).toString());
+
+        runningYarnApps = (Set<String>) runningYarnAppsField.get(mrRunningJobFetchSpout);
+        Assert.assertEquals(1, runningYarnApps.size());
+        Assert.assertEquals("[application_1479206441898_30784]", runningYarnApps.toString());
+
+    }
+
+    private MRRunningJobFetchSpout makeMrRunningJobFetchSpout() throws Exception {
+
+        mockInputSteam("/previousmrrunningapp.json");
+
+        MRRunningJobConfig mrRunningJobConfig = MRRunningJobConfig.newInstance(ConfigFactory.load());
+        mrRunningJobConfig.getEndpointConfig().fetchRunningJobInterval = 1;
+        MRRunningJobManager mrRunningJobManager = mock(MRRunningJobManager.class);
+        PowerMockito.whenNew(MRRunningJobManager.class).withArguments(mrRunningJobConfig.getZkStateConfig()).thenReturn(mrRunningJobManager);
+
+        InputStream app35341 = this.getClass().getResourceAsStream("/application_1479206441898_35341.json");
+        AppsWrapper appWrapper = OBJ_MAPPER.readValue(app35341, AppsWrapper.class);
+        List<AppInfo> appInfos = appWrapper.getApps().getApp();
+        Map<String, JobExecutionAPIEntity> jobs = new HashMap<>();
+        JobExecutionAPIEntity jobExecutionAPIEntity = new JobExecutionAPIEntity();
+        jobExecutionAPIEntity.setAppInfo(appInfos.get(0));
+        jobs.put("jobId", jobExecutionAPIEntity);
+        when(mrRunningJobManager.recoverYarnApp("application_1479206441898_35341")).thenReturn(jobs);
+
+        return new MRRunningJobFetchSpout(mrRunningJobConfig.getEndpointConfig(), mrRunningJobConfig.getZkStateConfig());
+    }
+    private void mockInputSteam(String mockDataFilePath) throws Exception {
+        InputStream jsonstream = this.getClass().getResourceAsStream(mockDataFilePath);
+        mockStatic(InputStreamUtils.class);
+        when(InputStreamUtils.getInputStream(RM_URL, null, Constants.CompressionType.GZIP)).thenReturn(jsonstream);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/7499be69/eagle-jpm/eagle-jpm-mr-running/src/test/resources/application_1479206441898_35341.json
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-mr-running/src/test/resources/application_1479206441898_35341.json b/eagle-jpm/eagle-jpm-mr-running/src/test/resources/application_1479206441898_35341.json
new file mode 100644
index 0000000..7c5906d
--- /dev/null
+++ b/eagle-jpm/eagle-jpm-mr-running/src/test/resources/application_1479206441898_35341.json
@@ -0,0 +1,35 @@
+{
+  "apps": {
+    "app": [
+      {
+        "id": "application_1479206441898_35341",
+        "user": "yyy",
+        "name": "insert overwrite table inter...a.xxx(Stage-3)",
+        "queue": "yyy",
+        "state": "RUNNING",
+        "finalStatus": "UNDEFINED",
+        "progress": 59.545456,
+        "trackingUI": "ApplicationMaster",
+        "trackingUrl": "http://host.domain.com:8088/proxy/application_1479206441898_35341/",
+        "diagnostics": "",
+        "clusterId": 1479206441898,
+        "applicationType": "MAPREDUCE",
+        "applicationTags": "",
+        "startedTime": 1479341511477,
+        "finishedTime": 0,
+        "elapsedTime": 77619,
+        "amContainerLogs": "http://host.domain.com:8042/node/containerlogs/container_e11_1479206441898_35341_01_000005/yyy",
+        "amHostHttpAddress": "host.domain.com:8042",
+        "allocatedMB": 27648,
+        "allocatedVCores": 6,
+        "runningContainers": 6,
+        "memorySeconds": 4940802,
+        "vcoreSeconds": 1483,
+        "preemptedResourceMB": 0,
+        "preemptedResourceVCores": 0,
+        "numNonAMContainerPreempted": 0,
+        "numAMContainerPreempted": 0
+      }
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/7499be69/eagle-jpm/eagle-jpm-mr-running/src/test/resources/previousmrrunningapp.json
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-mr-running/src/test/resources/previousmrrunningapp.json b/eagle-jpm/eagle-jpm-mr-running/src/test/resources/previousmrrunningapp.json
new file mode 100644
index 0000000..64a20f8
--- /dev/null
+++ b/eagle-jpm/eagle-jpm-mr-running/src/test/resources/previousmrrunningapp.json
@@ -0,0 +1,64 @@
+{
+  "apps": {
+    "app": [
+      {
+        "id": "application_1479206441898_30784",
+        "user": "xxx",
+        "name": "oozie:launcher:T=shell:W=wf_co_xxx_xxx_v3:A=extract_org_data:ID=0002383-161115184801730-oozie-oozi-W",
+        "queue": "xxx",
+        "state": "RUNNING",
+        "finalStatus": "UNDEFINED",
+        "progress": 95.0,
+        "trackingUI": "ApplicationMaster",
+        "trackingUrl": "http://host.domain.com:8088/proxy/application_1479206441898_30784/",
+        "diagnostics": "",
+        "clusterId": 1479206441898,
+        "applicationType": "MAPREDUCE",
+        "applicationTags": "",
+        "startedTime": 1479328221694,
+        "finishedTime": 0,
+        "elapsedTime": 13367402,
+        "amContainerLogs": "http://host.domain.com:8088/node/containerlogs/container_e11_1479206441898_30784_01_000001/xxx",
+        "amHostHttpAddress": "host.domain.com:8088",
+        "allocatedMB": 3072,
+        "allocatedVCores": 2,
+        "runningContainers": 2,
+        "memorySeconds": 41051800,
+        "vcoreSeconds": 26728,
+        "preemptedResourceMB": 0,
+        "preemptedResourceVCores": 0,
+        "numNonAMContainerPreempted": 0,
+        "numAMContainerPreempted": 0
+      },
+      {
+        "id": "application_1479206441898_35341",
+        "user": "yyy",
+        "name": "insert overwrite table inter...a.xxx(Stage-3)",
+        "queue": "yyy",
+        "state": "RUNNING",
+        "finalStatus": "UNDEFINED",
+        "progress": 59.545456,
+        "trackingUI": "ApplicationMaster",
+        "trackingUrl": "http://host.domain.com:8088/proxy/application_1479206441898_35341/",
+        "diagnostics": "",
+        "clusterId": 1479206441898,
+        "applicationType": "MAPREDUCE",
+        "applicationTags": "",
+        "startedTime": 1479341511477,
+        "finishedTime": 0,
+        "elapsedTime": 77619,
+        "amContainerLogs": "http://host.domain.com:8042/node/containerlogs/container_e11_1479206441898_35341_01_000005/yyy",
+        "amHostHttpAddress": "host.domain.com:8042",
+        "allocatedMB": 27648,
+        "allocatedVCores": 6,
+        "runningContainers": 6,
+        "memorySeconds": 4940802,
+        "vcoreSeconds": 1483,
+        "preemptedResourceMB": 0,
+        "preemptedResourceVCores": 0,
+        "numNonAMContainerPreempted": 0,
+        "numAMContainerPreempted": 0
+      }
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-eagle/blob/7499be69/eagle-jpm/eagle-jpm-mr-running/src/test/resources/thistimemrrunningapp.json
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-mr-running/src/test/resources/thistimemrrunningapp.json b/eagle-jpm/eagle-jpm-mr-running/src/test/resources/thistimemrrunningapp.json
new file mode 100644
index 0000000..dbcbba5
--- /dev/null
+++ b/eagle-jpm/eagle-jpm-mr-running/src/test/resources/thistimemrrunningapp.json
@@ -0,0 +1,35 @@
+{
+  "apps": {
+    "app": [
+      {
+        "id": "application_1479206441898_30784",
+        "user": "xxx",
+        "name": "oozie:launcher:T=shell:W=wf_co_xxx_xxx_v3:A=extract_org_data:ID=0002383-161115184801730-oozie-oozi-W",
+        "queue": "xxx",
+        "state": "RUNNING",
+        "finalStatus": "UNDEFINED",
+        "progress": 95.0,
+        "trackingUI": "ApplicationMaster",
+        "trackingUrl": "http://host.domain.com:8088/proxy/application_1479206441898_30784/",
+        "diagnostics": "",
+        "clusterId": 1479206441898,
+        "applicationType": "MAPREDUCE",
+        "applicationTags": "",
+        "startedTime": 1479328221694,
+        "finishedTime": 0,
+        "elapsedTime": 13367402,
+        "amContainerLogs": "http://host.domain.com:8088/node/containerlogs/container_e11_1479206441898_30784_01_000001/xxx",
+        "amHostHttpAddress": "host.domain.com:8088",
+        "allocatedMB": 3072,
+        "allocatedVCores": 2,
+        "runningContainers": 2,
+        "memorySeconds": 41051800,
+        "vcoreSeconds": 26728,
+        "preemptedResourceMB": 0,
+        "preemptedResourceVCores": 0,
+        "numNonAMContainerPreempted": 0,
+        "numAMContainerPreempted": 0
+      }
+    ]
+  }
+}
\ No newline at end of file