DRILL-266:Build tools to interpret the output dumped by the diagnostic operator.
authorJinfeng Ni <jni@maprtech.com>
Sat, 9 Nov 2013 00:50:45 +0000 (16:50 -0800)
committerJacques Nadeau <jacques@apache.org>
Sat, 9 Nov 2013 00:50:45 +0000 (16:50 -0800)
distribution/src/assemble/bin.xml
distribution/src/resources/drill_dumpcat [new file with mode: 0755]
exec/java-exec/src/main/java/org/apache/drill/exec/cache/VectorAccessibleSerializable.java
exec/java-exec/src/main/java/org/apache/drill/exec/client/DumpCat.java [new file with mode: 0644]
exec/java-exec/src/main/java/org/apache/drill/exec/client/QuerySubmitter.java
exec/java-exec/src/main/java/org/apache/drill/exec/util/VectorUtil.java [new file with mode: 0644]
exec/java-exec/src/test/java/org/apache/drill/exec/client/DumpCatTest.java [new file with mode: 0644]

index 26de847..fdd6c70 100644 (file)
       <outputDirectory>bin</outputDirectory>
     </file>
     <file>
+      <source>src/resources/drill_dumpcat</source>
+      <outputDirectory>bin</outputDirectory>
+    </file>
+    <file>
       <source>src/resources/drill-override.conf</source>
       <outputDirectory>conf</outputDirectory>
     </file>
diff --git a/distribution/src/resources/drill_dumpcat b/distribution/src/resources/drill_dumpcat
new file mode 100755 (executable)
index 0000000..1747c9a
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+# 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.
+
+bin=`dirname "${BASH_SOURCE-$0}"`
+bin=`cd "$bin">/dev/null; pwd`
+
+. "$bin"/drill-config.sh
+
+if [ -z $JAVA_HOME ]
+then
+  JAVA=`which java`
+else
+  JAVA=`find -L $JAVA_HOME -name java | head -n 1`
+fi
+
+if [ -e $JAVA ]; then
+  echo ""
+else
+  echo "Java not found."
+  exit 1
+fi
+
+$JAVA -version 2>&1 | grep "version" | egrep -e "1.7" > /dev/null
+if [ $? -ne 0 ]; then
+  echo "Java 1.7 is required to run Apache Drill."
+  exit 1
+fi
+
+# get log directory
+if [ "$DRILL_LOG_DIR" = "" ]; then
+  export DRILL_LOG_DIR=/var/log/drill
+fi
+
+CP=$DRILL_HOME/jars/*:$CP
+CP=$DRILL_HOME/lib/*:$CP
+
+CP=$DRILL_CONF_DIR:$CP
+CP=$HADOOP_CLASSPATH:$CP
+
+DRILL_SHELL_JAVA_OPTS="$DRILL_SHELL_JAVA_OPTS -Dlog.path=$DRILL_LOG_DIR/drill_dumpcat.log"
+
+exec $JAVA $DRILL_SHELL_JAVA_OPTS $DRILL_JAVA_OPTS -cp $CP org.apache.drill.exec.client.DumpCat $@
index e5bb94b..7b4bc23 100644 (file)
@@ -98,6 +98,7 @@ public class VectorAccessibleSerializable implements DrillSerializable {
     UserBitShared.RecordBatchDef batchDef = UserBitShared.RecordBatchDef.parseDelimitedFrom(input);
     recordCount = batchDef.getRecordCount();
     if (batchDef.hasIsSelectionVector2() && batchDef.getIsSelectionVector2()) {
+
       if (sv2 == null) {
         sv2 = new SelectionVector2(allocator);
       }
@@ -197,7 +198,7 @@ public class VectorAccessibleSerializable implements DrillSerializable {
   public VectorAccessible get() {
     return va;
   }
-
+  
   public SelectionVector2 getSv2() {
     return sv2;
   }
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/client/DumpCat.java b/exec/java-exec/src/main/java/org/apache/drill/exec/client/DumpCat.java
new file mode 100644 (file)
index 0000000..ef0b1e1
--- /dev/null
@@ -0,0 +1,292 @@
+/**
+ * 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.drill.exec.client;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.drill.common.config.DrillConfig;
+import org.apache.drill.exec.cache.VectorAccessibleSerializable;
+import org.apache.drill.exec.memory.BufferAllocator;
+import org.apache.drill.exec.record.BatchSchema;
+import org.apache.drill.exec.record.MaterializedField;
+import org.apache.drill.exec.record.VectorAccessible;
+import org.apache.drill.exec.record.VectorContainer;
+import org.apache.drill.exec.record.VectorWrapper;
+import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
+import org.apache.drill.exec.util.VectorUtil;
+
+import com.beust.jcommander.IParameterValidator;
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.internal.Lists;
+
+public class DumpCat {
+
+  private final static BufferAllocator allocator = BufferAllocator.getAllocator(DrillConfig.create());
+
+  public static void main(String args[]) throws Exception {
+    DumpCat dumpCat = new DumpCat();
+
+    Options o = new Options();
+    JCommander jc = null;
+    try {
+      jc = new JCommander(o, args);
+      jc.setProgramName("./drill_dumpcat");
+    } catch (ParameterException e) {
+      System.out.println(e.getMessage());
+      String[] valid = {"-f", "file"};
+      new JCommander(o, valid).usage();
+      jc.usage();
+      System.exit(-1);
+    }
+    if (o.help) {
+      jc.usage();
+      System.exit(0);
+    }
+
+    /*Check if dump file exists*/
+    File file = new File(o.location);
+    if (!file.exists()) {
+      System.out.println(String.format("Trace file %s not created", o.location));
+      System.exit(-1);
+    }
+    FileInputStream input = new FileInputStream(file.getAbsoluteFile());
+
+    if (o.batch < 0) {
+      dumpCat.doQuery(input);
+    } else {
+      dumpCat.doBatch(input, o.batch, o.include_headers);
+    }
+
+    input.close();
+  }
+
+  /**
+   * Used to ensure the param "batch" is a non-negative number.
+   */
+  public static class BatchNumValidator implements IParameterValidator {
+    @Override
+    public void validate(String name, String value) throws ParameterException {
+      try {
+        int batch = Integer.parseInt(value);
+        if(batch < 0) {
+          throw new ParameterException("Parameter " + name + " should be non-negative number.");
+        }
+      } catch (NumberFormatException e) {
+        throw new ParameterException("Parameter " + name + " should be non-negative number.");
+      }
+
+    }
+  }
+
+  /**
+   *  Options as input to JCommander.
+   */
+  static class Options {
+    @Parameter(names = {"-f"}, description = "file containing dump", required=true)
+    public String location = null;
+
+    @Parameter(names = {"-batch"}, description = "id of batch to show", required=false, validateWith = BatchNumValidator.class)
+    public int batch = -1;
+
+    @Parameter(names = {"-include-headers"}, description = "whether include header of batch", required=false)
+    public boolean include_headers = false;
+
+    @Parameter(names = {"-h", "-help", "--help"}, description = "show usage", help=true)
+    public boolean help = false;
+   }
+
+  /**
+   * Contains : # of rows, # of selected rows, data size (byte #).
+   */
+  private class BatchMetaInfo {
+    private long rows = 0;
+    private long selectedRows = 0;
+    private long dataSize = 0;
+
+    public BatchMetaInfo () {
+    }
+
+    public BatchMetaInfo (long rows, long selectedRows, long dataSize) {
+      this.rows = rows;
+      this.selectedRows = selectedRows;
+      this.dataSize = dataSize;
+    }
+
+    public void add(BatchMetaInfo info2) {
+      this.rows += info2.rows;
+      this.selectedRows += info2.selectedRows;
+      this.dataSize += info2.dataSize;
+    }
+
+    public String toString() {
+      String avgRecSizeStr = null;
+      if (this.rows>0)
+        avgRecSizeStr = String.format("Average Record Size : %d ", this.dataSize/this.rows);
+      else 
+        avgRecSizeStr = "Average Record Size : 0";
+      
+      return String.format("Records : %d / %d \n", this.selectedRows, this.rows) +
+             avgRecSizeStr + 
+             String.format("\n Total Data Size : %d", this.dataSize);
+    }
+  }
+
+  /**
+   * Querymode:
+   * $drill-dumpcat --file=local:///tmp/drilltrace/[queryid]_[tag]_[majorid]_[minor]_[operator]
+   *   Batches: 135
+   *   Records: 53,214/53,214 // the first one is the selected records.  The second number is the total number of records.
+   *   Selected Records: 53,214
+   *   Average Record Size: 74 bytes
+   *   Total Data Size: 12,345 bytes
+   *   Number of Empty Batches: 1
+   *   Schema changes: 1
+   *   Schema change batch indices: 0
+   * @throws Exception
+   */
+  protected void doQuery(FileInputStream input) throws Exception{
+    int  batchNum = 0;
+    int  emptyBatchNum = 0;
+    BatchSchema prevSchema = null;
+    List<Integer> schemaChangeIdx = Lists.newArrayList();
+
+    BatchMetaInfo aggBatchMetaInfo = new BatchMetaInfo();
+
+    while (input.available() > 0) {
+      VectorAccessibleSerializable vcSerializable = new VectorAccessibleSerializable(DumpCat.allocator);
+      vcSerializable.readFromStream(input);
+       VectorContainer vectorContainer = (VectorContainer) vcSerializable.get();
+
+       aggBatchMetaInfo.add(getBatchMetaInfo(vcSerializable));
+
+       if (vectorContainer.getRecordCount() == 0) {
+         emptyBatchNum ++;
+       }
+
+       if (prevSchema != null && !vectorContainer.getSchema().equals(prevSchema))
+         schemaChangeIdx.add(batchNum);
+
+       prevSchema = vectorContainer.getSchema();
+       batchNum ++;
+       vectorContainer.zeroVectors();
+    }
+
+     /* output the summary stat */
+     System.out.println(String.format("Total # of batches: %d", batchNum));
+     //output: rows, selectedRows, avg rec size, total data size.
+     System.out.println(aggBatchMetaInfo.toString());
+     System.out.println(String.format("Empty batch : %d", emptyBatchNum));
+    System.out.println(String.format("Schema changes : %d", schemaChangeIdx.size()));
+    System.out.println(String.format("Schema change batch index : %s", schemaChangeIdx.toString()));
+  }
+
+  /**
+   * Batch mode:
+   * $drill-dumpcat --file=local:///tmp/drilltrace/[queryid]_[tag]_[majorid]_[minor]_[operator] --batch=123 --include-headers=true
+   * Records: 1/1
+   * Average Record Size: 8 bytes
+   * Total Data Size: 8 bytes
+   * Schema Information
+   * name: col1, minor_type: int4, data_mode: nullable
+   * name: col2, minor_type: int4, data_mode: non-nullable
+   * @param targetBatchNum
+   * @throws Exception
+   */
+  protected void doBatch(FileInputStream input, int targetBatchNum, boolean showHeader) throws Exception {
+    int batchNum = -1;
+
+    VectorAccessibleSerializable vcSerializable = null;
+
+    while (input.available() > 0 && batchNum ++ < targetBatchNum) {
+      vcSerializable = new VectorAccessibleSerializable(DumpCat.allocator);
+      vcSerializable.readFromStream(input);
+
+      if (batchNum != targetBatchNum) {
+        VectorContainer vectorContainer = (VectorContainer) vcSerializable.get();
+        vectorContainer.zeroVectors();
+      }
+    }
+
+    if (batchNum < targetBatchNum) {
+      System.out.println(String.format("Wrong input of batch # ! Total # of batch in the file is %d. Please input a number 0..%d as batch #", batchNum+1, batchNum));
+      input.close();
+      System.exit(-1);
+    }
+
+    if (vcSerializable != null) {
+      showSingleBatch(vcSerializable, showHeader);
+      VectorContainer vectorContainer = (VectorContainer) vcSerializable.get();
+      vectorContainer.zeroVectors();
+    }
+  }
+
+
+  private void showSingleBatch (VectorAccessibleSerializable vcSerializable, boolean showHeader) {
+    VectorContainer vectorContainer = (VectorContainer)vcSerializable.get();
+
+    /* show the header of the batch */
+    if (showHeader) {
+      System.out.println(getBatchMetaInfo(vcSerializable).toString());
+
+      System.out.println("Schema Information");
+      for (VectorWrapper w : vectorContainer) {
+        MaterializedField field = w.getValueVector().getField();
+        System.out.println (String.format("name : %s, minor_type : %s, data_mode : %s",
+                                          field.getName(),
+                                          field.getType().getMinorType().toString(),
+                                          field.isNullable() ? "nullable":"non-nullable"
+                          ));
+      }
+    }
+
+    /* show the contents in the batch */
+    VectorUtil.showVectorAccessibleContent(vectorContainer);
+  }
+
+
+  /* Get batch meta info : rows, selectedRows, dataSize */
+  private BatchMetaInfo getBatchMetaInfo(VectorAccessibleSerializable vcSerializable) {
+    VectorAccessible vectorContainer = vcSerializable.get();
+
+    int rows =0;
+    int selectedRows = 0;
+    int totalDataSize = 0;
+
+    rows = vectorContainer.getRecordCount();
+    selectedRows = rows;
+
+    if (vectorContainer.getSchema().getSelectionVectorMode() == SelectionVectorMode.TWO_BYTE) {
+      selectedRows = vcSerializable.getSv2().getCount();
+    }
+
+    for (VectorWrapper w : vectorContainer) {
+       totalDataSize += w.getValueVector().getBufferSize();
+    }
+
+    return new   BatchMetaInfo(rows, selectedRows, totalDataSize);
+  }
+
+}
index c34ab1f..554fad0 100644 (file)
@@ -25,6 +25,7 @@ import com.beust.jcommander.internal.Lists;
 import com.google.common.base.Charsets;
 import com.google.common.base.Stopwatch;
 import com.google.common.io.Resources;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.drill.common.config.DrillConfig;
 import org.apache.drill.exec.coord.ClusterCoordinator;
@@ -40,6 +41,7 @@ import org.apache.drill.exec.rpc.user.UserResultsListener;
 import org.apache.drill.exec.server.BootStrapContext;
 import org.apache.drill.exec.server.Drillbit;
 import org.apache.drill.exec.server.RemoteServiceSet;
+import org.apache.drill.exec.util.VectorUtil;
 import org.apache.drill.exec.vector.ValueVector;
 
 import java.io.IOException;
@@ -156,35 +158,12 @@ public class QuerySubmitter {
         } catch (SchemaChangeException e) {
           submissionFailed(new RpcException(e));
         }
-        List<String> columns = Lists.newArrayList();
-        for (VectorWrapper vw : loader) {
-          columns.add(vw.getValueVector().getField().getName());
-        }
-        width = columns.size();
-        for (int row = 0; row < rows; row++) {
-          if (row%50 == 0) {
-            System.out.println(StringUtils.repeat("-", width*17 + 1));
-            for (String column : columns) {
-              System.out.printf("| %-15s", width <= 15 ? column : column.substring(0, 14));
-            }
-            System.out.printf("|\n");
-            System.out.println(StringUtils.repeat("-", width*17 + 1));
-          }
-          for (VectorWrapper vw : loader) {
-            Object o = vw.getValueVector().getAccessor().getObject(row);
-            if (o instanceof byte[]) {
-              String value = new String((byte[]) o);
-              System.out.printf("| %-15s",value.length() <= 15 ? value : value.substring(0, 14));
-            } else {
-              String value = o.toString();
-              System.out.printf("| %-15s",value.length() <= 15 ? value : value.substring(0,14));
-            }
-          }
-          System.out.printf("|\n");
-        }
+        
+        VectorUtil.showVectorAccessibleContent(loader);
       }
+      
       if (result.getHeader().getIsLastChunk()) {
-        System.out.println(StringUtils.repeat("-", width*17 + 1));
+        //System.out.println(StringUtils.repeat("-", width*17 + 1));
         latch.countDown();
       }
       result.release();
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/util/VectorUtil.java b/exec/java-exec/src/main/java/org/apache/drill/exec/util/VectorUtil.java
new file mode 100644 (file)
index 0000000..8b23bcd
--- /dev/null
@@ -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.drill.exec.util;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.drill.exec.exception.SchemaChangeException;
+import org.apache.drill.exec.record.VectorAccessible;
+import org.apache.drill.exec.record.VectorWrapper;
+import org.apache.drill.exec.rpc.RpcException;
+
+import com.beust.jcommander.internal.Lists;
+
+public class VectorUtil {
+
+  public static void showVectorAccessibleContent(VectorAccessible va) {
+
+    int rows = va.getRecordCount();
+    List<String> columns = Lists.newArrayList();
+    for (VectorWrapper vw : va) {
+      columns.add(vw.getValueVector().getField().getName());
+    }
+
+    int width = columns.size();
+    for (int row = 0; row < rows; row++) {
+      if (row%50 == 0) {
+        System.out.println(StringUtils.repeat("-", width*17 + 1));
+        for (String column : columns) {
+          System.out.printf("| %-15s", column.length() <= 15 ? column : column.substring(0, 14));
+        }
+        System.out.printf("|\n");
+        System.out.println(StringUtils.repeat("-", width*17 + 1));
+      }
+      for (VectorWrapper vw : va) {
+        Object o = vw.getValueVector().getAccessor().getObject(row);
+        if (o instanceof byte[]) {
+          String value = new String((byte[]) o);
+          System.out.printf("| %-15s",value.length() <= 15 ? value : value.substring(0, 14));
+        } else {
+          String value = o.toString();
+          System.out.printf("| %-15s",value.length() <= 15 ? value : value.substring(0,14));
+        }
+      }
+      System.out.printf("|\n");
+    }
+
+    if (rows > 0 )
+      System.out.println(StringUtils.repeat("-", width*17 + 1));
+  }
+
+
+}
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/client/DumpCatTest.java b/exec/java-exec/src/test/java/org/apache/drill/exec/client/DumpCatTest.java
new file mode 100644 (file)
index 0000000..7a9784b
--- /dev/null
@@ -0,0 +1,133 @@
+/**
+ * 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.drill.exec.client;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileInputStream;
+
+import mockit.Injectable;
+import mockit.NonStrictExpectations;
+
+import org.apache.drill.common.config.DrillConfig;
+import org.apache.drill.common.util.FileUtils;
+import org.apache.drill.exec.ExecConstants;
+
+import org.apache.drill.exec.expr.fn.FunctionImplementationRegistry;
+import org.apache.drill.exec.memory.BufferAllocator;
+import org.apache.drill.exec.ops.FragmentContext;
+import org.apache.drill.exec.physical.PhysicalPlan;
+import org.apache.drill.exec.physical.base.FragmentRoot;
+import org.apache.drill.exec.physical.impl.ImplCreator;
+import org.apache.drill.exec.physical.impl.SimpleRootExec;
+
+import org.apache.drill.exec.planner.PhysicalPlanReader;
+import org.apache.drill.exec.proto.CoordinationProtos;
+import org.apache.drill.exec.proto.ExecProtos.FragmentHandle;
+import org.apache.drill.exec.proto.helper.QueryIdHelper;
+
+import org.apache.drill.exec.rpc.user.UserServer.UserClientConnection;
+import org.apache.drill.exec.server.DrillbitContext;
+import org.apache.hadoop.conf.Configuration;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import com.yammer.metrics.MetricRegistry;
+
+/**
+ * The unit test case will read a physical plan in json format. The physical plan contains a "trace" operator,
+ * which will produce a dump file.  The dump file will be input into DumpCat to test query mode and batch mode.
+ */
+
+public class DumpCatTest {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DumpCatTest.class);
+  DrillConfig c = DrillConfig.create();
+  @Test
+  public void testDumpCat(@Injectable final DrillbitContext bitContext, @Injectable UserClientConnection connection) throws Throwable
+  {
+
+      new NonStrictExpectations(){{
+          bitContext.getMetrics(); result = new MetricRegistry("test");
+          bitContext.getAllocator(); result = BufferAllocator.getAllocator(c);
+          bitContext.getConfig(); result = c;
+      }};
+
+      PhysicalPlanReader reader = new PhysicalPlanReader(c, c.getMapper(), CoordinationProtos.DrillbitEndpoint.getDefaultInstance());
+      PhysicalPlan plan = reader.readPhysicalPlan(Files.toString(FileUtils.getResourceAsFile("/trace/simple_trace.json"), Charsets.UTF_8));
+      FunctionImplementationRegistry registry = new FunctionImplementationRegistry(c);
+      FragmentContext context = new FragmentContext(bitContext, FragmentHandle.getDefaultInstance(), connection, null, registry);
+      SimpleRootExec exec = new SimpleRootExec(ImplCreator.getExec(context, (FragmentRoot) plan.getSortedOperators(false).iterator().next()));
+
+      while(exec.next()){
+      }
+
+      if(context.getFailureCause() != null){
+          throw context.getFailureCause();
+      }
+      assertTrue(!context.isFailed());
+
+      FragmentHandle handle = context.getHandle();
+
+      /* Form the file name to which the trace output will dump the record batches */
+      String qid = QueryIdHelper.getQueryId(handle.getQueryId());
+
+      int majorFragmentId = handle.getMajorFragmentId();
+      int minorFragmentId = handle.getMinorFragmentId();
+
+      String logLocation = c.getString(ExecConstants.TRACE_DUMP_DIRECTORY);
+
+      System.out.println("Found log location: " + logLocation);
+
+      String filename = String.format("%s//%s_%d_%d_mock-scan", logLocation, qid, majorFragmentId, minorFragmentId);
+
+      System.out.println("File Name: " + filename);
+
+      Configuration conf = new Configuration();
+      conf.set("fs.name.default", c.getString(ExecConstants.TRACE_DUMP_FILESYSTEM));
+
+      FileSystem fs = FileSystem.get(conf);
+      Path path = new Path(filename);
+      assertTrue("Trace file does not exist", fs.exists(path));
+      DumpCat dumpCat = new DumpCat();
+      //Test Query mode
+      FileInputStream input = new FileInputStream(filename);
+      dumpCat.doQuery(input);
+      input.close();
+
+      //Test Batch mode
+      input = new FileInputStream(filename);
+      dumpCat.doBatch(input,0,true);
+
+      input.close();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception{
+      // pause to get logger to catch up.
+      Thread.sleep(1000);
+  }
+}