You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@giraph.apache.org by jg...@apache.org on 2012/06/21 20:34:11 UTC

svn commit: r1352647 - in /giraph/trunk: ./ src/main/java/org/apache/giraph/examples/ src/main/java/org/apache/giraph/lib/ src/test/java/org/apache/giraph/ src/test/java/org/apache/giraph/examples/

Author: jghoman
Date: Thu Jun 21 18:34:10 2012
New Revision: 1352647

URL: http://svn.apache.org/viewvc?rev=1352647&view=rev
Log:
GIRAPH-206. Break out SimpleShortestPathVertex. Contributed by Eli Reisman.

Added:
    giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexInputFormat.java
    giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexOutputFormat.java
    giraph/trunk/src/test/java/org/apache/giraph/examples/SimpleShortestPathsVertexTest.java
Removed:
    giraph/trunk/src/test/java/org/apache/giraph/examples/SimpleShortestPathVertexTest.java
Modified:
    giraph/trunk/CHANGELOG
    giraph/trunk/src/main/java/org/apache/giraph/examples/SimpleShortestPathsVertex.java
    giraph/trunk/src/test/java/org/apache/giraph/TestBspBasic.java

Modified: giraph/trunk/CHANGELOG
URL: http://svn.apache.org/viewvc/giraph/trunk/CHANGELOG?rev=1352647&r1=1352646&r2=1352647&view=diff
==============================================================================
--- giraph/trunk/CHANGELOG (original)
+++ giraph/trunk/CHANGELOG Thu Jun 21 18:34:10 2012
@@ -2,6 +2,8 @@ Giraph Change Log
 
 Release 0.2.0 - unreleased
 
+  GIRAPH-206: Break out SimpleShortestPathVertex. (Eli Reisman via jghoman)
+
   GIRAPH-210: Hadoop 1.0 profile has no activation. (jghoman)
  
   GIRAPH-192: Move aggregators to a separate sub-package. 

Modified: giraph/trunk/src/main/java/org/apache/giraph/examples/SimpleShortestPathsVertex.java
URL: http://svn.apache.org/viewvc/giraph/trunk/src/main/java/org/apache/giraph/examples/SimpleShortestPathsVertex.java?rev=1352647&r1=1352646&r2=1352647&view=diff
==============================================================================
--- giraph/trunk/src/main/java/org/apache/giraph/examples/SimpleShortestPathsVertex.java (original)
+++ giraph/trunk/src/main/java/org/apache/giraph/examples/SimpleShortestPathsVertex.java Thu Jun 21 18:34:10 2012
@@ -18,46 +18,20 @@
 
 package org.apache.giraph.examples;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import org.apache.giraph.graph.BasicVertex;
-import org.apache.giraph.graph.BspUtils;
-import org.apache.giraph.graph.GiraphJob;
 import org.apache.giraph.graph.EdgeListVertex;
-import org.apache.giraph.graph.VertexReader;
-import org.apache.giraph.graph.VertexWriter;
-import org.apache.giraph.lib.TextVertexInputFormat;
-import org.apache.giraph.lib.TextVertexInputFormat.TextVertexReader;
-import org.apache.giraph.lib.TextVertexOutputFormat;
-import org.apache.giraph.lib.TextVertexOutputFormat.TextVertexWriter;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.DoubleWritable;
 import org.apache.hadoop.io.FloatWritable;
 import org.apache.hadoop.io.LongWritable;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.mapreduce.InputSplit;
-import org.apache.hadoop.mapreduce.RecordReader;
-import org.apache.hadoop.mapreduce.RecordWriter;
-import org.apache.hadoop.mapreduce.TaskAttemptContext;
-import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
-import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
-import org.apache.hadoop.util.Tool;
-import org.apache.hadoop.util.ToolRunner;
 import org.apache.log4j.Logger;
-import org.json.JSONArray;
-import org.json.JSONException;
 
-import java.io.IOException;
 import java.util.Iterator;
-import java.util.Map;
 
 /**
  * Demonstrates the basic Pregel shortest paths implementation.
  */
 public class SimpleShortestPathsVertex extends
     EdgeListVertex<LongWritable, DoubleWritable,
-    FloatWritable, DoubleWritable> implements Tool {
+    FloatWritable, DoubleWritable> {
   /** The shortest paths id */
   public static final String SOURCE_ID = "SimpleShortestPathsVertex.sourceId";
   /** Default shortest paths id */
@@ -65,8 +39,6 @@ public class SimpleShortestPathsVertex e
   /** Class logger */
   private static final Logger LOG =
       Logger.getLogger(SimpleShortestPathsVertex.class);
-  /** Configuration */
-  private Configuration conf;
 
   /**
    * Is this vertex the source id?
@@ -107,181 +79,4 @@ public class SimpleShortestPathsVertex e
     }
     voteToHalt();
   }
-
-  /**
-   * VertexInputFormat that supports {@link SimpleShortestPathsVertex}
-   */
-  public static class SimpleShortestPathsVertexInputFormat extends
-      TextVertexInputFormat<LongWritable, DoubleWritable,
-      FloatWritable, DoubleWritable> {
-    @Override
-    public VertexReader<LongWritable, DoubleWritable, FloatWritable,
-    DoubleWritable> createVertexReader(InputSplit split,
-      TaskAttemptContext context)
-      throws IOException {
-      return new SimpleShortestPathsVertexReader(
-          textInputFormat.createRecordReader(split, context));
-    }
-  }
-
-  /**
-   * VertexReader that supports {@link SimpleShortestPathsVertex}.  In this
-   * case, the edge values are not used.  The files should be in the
-   * following JSON format:
-   * JSONArray(<vertex id>, <vertex value>,
-   *           JSONArray(JSONArray(<dest vertex id>, <edge value>), ...))
-   * Here is an example with vertex id 1, vertex value 4.3, and two edges.
-   * First edge has a destination vertex 2, edge value 2.1.
-   * Second edge has a destination vertex 3, edge value 0.7.
-   * [1,4.3,[[2,2.1],[3,0.7]]]
-   */
-  public static class SimpleShortestPathsVertexReader extends
-      TextVertexReader<LongWritable, DoubleWritable,
-      FloatWritable, DoubleWritable> {
-
-    /**
-     * Constructor with the line record reader.
-     *
-     * @param lineRecordReader Will read from this line.
-     */
-    public SimpleShortestPathsVertexReader(
-        RecordReader<LongWritable, Text> lineRecordReader) {
-      super(lineRecordReader);
-    }
-
-    @Override
-    public BasicVertex<LongWritable, DoubleWritable, FloatWritable,
-    DoubleWritable> getCurrentVertex()
-      throws IOException, InterruptedException {
-      BasicVertex<LongWritable, DoubleWritable, FloatWritable,
-      DoubleWritable> vertex =
-        BspUtils.<LongWritable, DoubleWritable, FloatWritable,
-          DoubleWritable>createVertex(getContext().getConfiguration());
-
-      Text line = getRecordReader().getCurrentValue();
-      try {
-        JSONArray jsonVertex = new JSONArray(line.toString());
-        LongWritable vertexId = new LongWritable(jsonVertex.getLong(0));
-        DoubleWritable vertexValue =
-            new DoubleWritable(jsonVertex.getDouble(1));
-        Map<LongWritable, FloatWritable> edges = Maps.newHashMap();
-        JSONArray jsonEdgeArray = jsonVertex.getJSONArray(2);
-        for (int i = 0; i < jsonEdgeArray.length(); ++i) {
-          JSONArray jsonEdge = jsonEdgeArray.getJSONArray(i);
-          edges.put(new LongWritable(jsonEdge.getLong(0)),
-              new FloatWritable((float) jsonEdge.getDouble(1)));
-        }
-        vertex.initialize(vertexId, vertexValue, edges, null);
-      } catch (JSONException e) {
-        throw new IllegalArgumentException(
-            "next: Couldn't get vertex from line " + line, e);
-      }
-      return vertex;
-    }
-
-    @Override
-    public boolean nextVertex() throws IOException, InterruptedException {
-      return getRecordReader().nextKeyValue();
-    }
-  }
-
-  /**
-   * VertexOutputFormat that supports {@link SimpleShortestPathsVertex}
-   */
-  public static class SimpleShortestPathsVertexOutputFormat extends
-      TextVertexOutputFormat<LongWritable, DoubleWritable,
-      FloatWritable> {
-    @Override
-    public VertexWriter<LongWritable, DoubleWritable, FloatWritable>
-    createVertexWriter(TaskAttemptContext context)
-      throws IOException, InterruptedException {
-      RecordWriter<Text, Text> recordWriter =
-          textOutputFormat.getRecordWriter(context);
-      return new SimpleShortestPathsVertexWriter(recordWriter);
-    }
-  }
-
-  /**
-   * VertexWriter that supports {@link SimpleShortestPathsVertex}
-   */
-  public static class SimpleShortestPathsVertexWriter extends
-      TextVertexWriter<LongWritable, DoubleWritable, FloatWritable> {
-    /**
-     * Vertex writer with the internal line writer.
-     *
-     * @param lineRecordWriter Wil actually be written to.
-     */
-    public SimpleShortestPathsVertexWriter(
-        RecordWriter<Text, Text> lineRecordWriter) {
-      super(lineRecordWriter);
-    }
-
-    @Override
-    public void writeVertex(BasicVertex<LongWritable, DoubleWritable,
-      FloatWritable, ?> vertex)
-      throws IOException, InterruptedException {
-      JSONArray jsonVertex = new JSONArray();
-      try {
-        jsonVertex.put(vertex.getVertexId().get());
-        jsonVertex.put(vertex.getVertexValue().get());
-        JSONArray jsonEdgeArray = new JSONArray();
-        for (LongWritable targetVertexId : vertex) {
-          JSONArray jsonEdge = new JSONArray();
-          jsonEdge.put(targetVertexId.get());
-          jsonEdge.put(vertex.getEdgeValue(targetVertexId).get());
-          jsonEdgeArray.put(jsonEdge);
-        }
-        jsonVertex.put(jsonEdgeArray);
-      } catch (JSONException e) {
-        throw new IllegalArgumentException(
-            "writeVertex: Couldn't write vertex " + vertex);
-      }
-      getRecordWriter().write(new Text(jsonVertex.toString()), null);
-    }
-  }
-
-  @Override
-  public Configuration getConf() {
-    return conf;
-  }
-
-  @Override
-  public void setConf(Configuration conf) {
-    this.conf = conf;
-  }
-
-  @Override
-  public int run(String[] argArray) throws Exception {
-    Preconditions.checkArgument(argArray.length == 4,
-        "run: Must have 4 arguments <input path> <output path> " +
-        "<source vertex id> <# of workers>");
-
-    GiraphJob job = new GiraphJob(getConf(), getClass().getName());
-    job.setVertexClass(getClass());
-    job.setVertexInputFormatClass(
-        SimpleShortestPathsVertexInputFormat.class);
-    job.setVertexOutputFormatClass(
-        SimpleShortestPathsVertexOutputFormat.class);
-    FileInputFormat.addInputPath(job.getInternalJob(),
-                                 new Path(argArray[0]));
-    FileOutputFormat.setOutputPath(job.getInternalJob(),
-                                   new Path(argArray[1]));
-    job.getConfiguration().setLong(SimpleShortestPathsVertex.SOURCE_ID,
-        Long.parseLong(argArray[2]));
-    job.setWorkerConfiguration(Integer.parseInt(argArray[3]),
-        Integer.parseInt(argArray[3]),
-        100.0f);
-
-    return job.run(true) ? 0 : -1;
-  }
-
-  /**
-   * Can be used for command line execution.
-   *
-   * @param args Command line arguments.
-   * @throws Exception
-   */
-  public static void main(String[] args) throws Exception {
-    System.exit(ToolRunner.run(new SimpleShortestPathsVertex(), args));
-  }
 }

Added: giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexInputFormat.java
URL: http://svn.apache.org/viewvc/giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexInputFormat.java?rev=1352647&view=auto
==============================================================================
--- giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexInputFormat.java (added)
+++ giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexInputFormat.java Thu Jun 21 18:34:10 2012
@@ -0,0 +1,114 @@
+/*
+ * 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.giraph.lib;
+
+import org.apache.giraph.graph.VertexReader;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import com.google.common.collect.Maps;
+import org.apache.giraph.graph.BasicVertex;
+import org.apache.giraph.graph.BspUtils;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+  * VertexInputFormat that features <code>long</code> vertex ID's,
+  * <code>double</code> vertex values and <code>float</code>
+  * out-edge weights, and <code>double</code> message types,
+  *  specified in JSON format.
+  */
+public class JsonLongDoubleFloatDoubleVertexInputFormat extends
+  TextVertexInputFormat<LongWritable, DoubleWritable,
+  FloatWritable, DoubleWritable> {
+
+  @Override
+  public VertexReader<LongWritable, DoubleWritable, FloatWritable,
+    DoubleWritable> createVertexReader(InputSplit split,
+    TaskAttemptContext context) throws IOException {
+    return new JsonLongDoubleFloatDoubleVertexReader(
+      textInputFormat.createRecordReader(split, context));
+  }
+
+ /**
+  * VertexReader that features <code>double</code> vertex
+  * values and <code>float</code> out-edge weights. The
+  * files should be in the following JSON format:
+  * JSONArray(<vertex id>, <vertex value>,
+  *   JSONArray(JSONArray(<dest vertex id>, <edge value>), ...))
+  * Here is an example with vertex id 1, vertex value 4.3, and two edges.
+  * First edge has a destination vertex 2, edge value 2.1.
+  * Second edge has a destination vertex 3, edge value 0.7.
+  * [1,4.3,[[2,2.1],[3,0.7]]]
+  */
+  static class JsonLongDoubleFloatDoubleVertexReader extends
+    TextVertexReader<LongWritable, DoubleWritable,
+    FloatWritable, DoubleWritable> {
+
+  /**
+    * Constructor with the line record reader.
+    *
+    * @param lineRecordReader Will read from this line.
+    */
+    public JsonLongDoubleFloatDoubleVertexReader(
+      RecordReader<LongWritable, Text> lineRecordReader) {
+      super(lineRecordReader);
+    }
+
+    @Override
+    public BasicVertex<LongWritable, DoubleWritable, FloatWritable,
+      DoubleWritable> getCurrentVertex()
+      throws IOException, InterruptedException {
+      BasicVertex<LongWritable, DoubleWritable, FloatWritable,
+      DoubleWritable> vertex =
+        BspUtils.<LongWritable, DoubleWritable, FloatWritable,
+          DoubleWritable>createVertex(getContext().getConfiguration());
+
+      Text line = getRecordReader().getCurrentValue();
+      try {
+        JSONArray jsonVertex = new JSONArray(line.toString());
+        LongWritable vertexId = new LongWritable(jsonVertex.getLong(0));
+        DoubleWritable vertexValue =
+          new DoubleWritable(jsonVertex.getDouble(1));
+        Map<LongWritable, FloatWritable> edges = Maps.newHashMap();
+        JSONArray jsonEdgeArray = jsonVertex.getJSONArray(2);
+        for (int i = 0; i < jsonEdgeArray.length(); ++i) {
+          JSONArray jsonEdge = jsonEdgeArray.getJSONArray(i);
+          edges.put(new LongWritable(jsonEdge.getLong(0)),
+            new FloatWritable((float) jsonEdge.getDouble(1)));
+        }
+        vertex.initialize(vertexId, vertexValue, edges, null);
+      } catch (JSONException e) {
+        throw new IllegalArgumentException(
+          "next: Couldn't get vertex from line " + line, e);
+      }
+      return vertex;
+    }
+
+    @Override
+    public boolean nextVertex() throws IOException, InterruptedException {
+      return getRecordReader().nextKeyValue();
+    }
+  }
+}

Added: giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexOutputFormat.java
URL: http://svn.apache.org/viewvc/giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexOutputFormat.java?rev=1352647&view=auto
==============================================================================
--- giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexOutputFormat.java (added)
+++ giraph/trunk/src/main/java/org/apache/giraph/lib/JsonLongDoubleFloatDoubleVertexOutputFormat.java Thu Jun 21 18:34:10 2012
@@ -0,0 +1,88 @@
+/*
+ * 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.giraph.lib;
+
+import org.apache.giraph.graph.VertexWriter;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.mapreduce.RecordWriter;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.giraph.graph.BasicVertex;
+import java.io.IOException;
+
+/**
+ * VertexOutputFormat that supports JSON encoded vertices featuring
+ * <code>double</code> values and <code>float</code> out-edge weights
+ */
+public class JsonLongDoubleFloatDoubleVertexOutputFormat extends
+  TextVertexOutputFormat<LongWritable, DoubleWritable,
+  FloatWritable> {
+  @Override
+  public VertexWriter<LongWritable, DoubleWritable, FloatWritable>
+  createVertexWriter(TaskAttemptContext context)
+    throws IOException, InterruptedException {
+    RecordWriter<Text, Text> recordWriter =
+      textOutputFormat.getRecordWriter(context);
+    return new JsonLongDoubleFloatDoubleVertexWriter(recordWriter);
+  }
+
+ /**
+  * VertexWriter that supports vertices with <code>double</code>
+  * values and <code>float</code> out-edge weights.
+  */
+  static class JsonLongDoubleFloatDoubleVertexWriter extends
+    TextVertexWriter<LongWritable, DoubleWritable, FloatWritable> {
+
+   /**
+    * Vertex writer with the internal line writer.
+    *
+    * @param lineRecordWriter Wil actually be written to.
+    */
+    public JsonLongDoubleFloatDoubleVertexWriter(
+      RecordWriter<Text, Text> lineRecordWriter) {
+      super(lineRecordWriter);
+    }
+
+    @Override
+    public void writeVertex(BasicVertex<LongWritable, DoubleWritable,
+      FloatWritable, ?> vertex) throws IOException, InterruptedException {
+      JSONArray jsonVertex = new JSONArray();
+      try {
+        jsonVertex.put(vertex.getVertexId().get());
+        jsonVertex.put(vertex.getVertexValue().get());
+        JSONArray jsonEdgeArray = new JSONArray();
+        for (LongWritable targetVertexId : vertex) {
+          JSONArray jsonEdge = new JSONArray();
+          jsonEdge.put(targetVertexId.get());
+          jsonEdge.put(vertex.getEdgeValue(targetVertexId).get());
+          jsonEdgeArray.put(jsonEdge);
+        }
+        jsonVertex.put(jsonEdgeArray);
+      } catch (JSONException e) {
+        throw new IllegalArgumentException(
+          "writeVertex: Couldn't write vertex " + vertex);
+      }
+      getRecordWriter().write(new Text(jsonVertex.toString()), null);
+    }
+  }
+}

Modified: giraph/trunk/src/test/java/org/apache/giraph/TestBspBasic.java
URL: http://svn.apache.org/viewvc/giraph/trunk/src/test/java/org/apache/giraph/TestBspBasic.java?rev=1352647&r1=1352646&r2=1352647&view=diff
==============================================================================
--- giraph/trunk/src/test/java/org/apache/giraph/TestBspBasic.java (original)
+++ giraph/trunk/src/test/java/org/apache/giraph/TestBspBasic.java Thu Jun 21 18:34:10 2012
@@ -36,7 +36,7 @@ import org.apache.giraph.examples.Simple
 import org.apache.giraph.examples.SimplePageRankVertex;
 import org.apache.giraph.examples.SimplePageRankVertex.SimplePageRankVertexInputFormat;
 import org.apache.giraph.examples.SimpleShortestPathsVertex;
-import org.apache.giraph.examples.SimpleShortestPathsVertex.SimpleShortestPathsVertexOutputFormat;
+import org.apache.giraph.lib.JsonLongDoubleFloatDoubleVertexOutputFormat;
 import org.apache.giraph.examples.SimpleSumCombiner;
 import org.apache.giraph.examples.SimpleSuperstepVertex;
 import org.apache.giraph.examples.SimpleSuperstepVertex.SimpleSuperstepVertexInputFormat;
@@ -311,7 +311,7 @@ public class TestBspBasic extends BspCas
     GiraphJob job = prepareJob(getCallingMethodName(),
         SimpleShortestPathsVertex.class,
         SimplePageRankVertex.SimplePageRankVertexInputFormat.class,
-        SimpleShortestPathsVertex.SimpleShortestPathsVertexOutputFormat.class,
+        JsonLongDoubleFloatDoubleVertexOutputFormat.class,
         outputPath);
     Configuration conf = job.getConfiguration();
     conf.setLong(SimpleShortestPathsVertex.SOURCE_ID, 0);

Added: giraph/trunk/src/test/java/org/apache/giraph/examples/SimpleShortestPathsVertexTest.java
URL: http://svn.apache.org/viewvc/giraph/trunk/src/test/java/org/apache/giraph/examples/SimpleShortestPathsVertexTest.java?rev=1352647&view=auto
==============================================================================
--- giraph/trunk/src/test/java/org/apache/giraph/examples/SimpleShortestPathsVertexTest.java (added)
+++ giraph/trunk/src/test/java/org/apache/giraph/examples/SimpleShortestPathsVertexTest.java Thu Jun 21 18:34:10 2012
@@ -0,0 +1,157 @@
+/*
+ * 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.giraph.examples;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.apache.giraph.utils.InternalVertexRunner;
+import org.apache.giraph.utils.MockUtils;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.giraph.lib.JsonLongDoubleFloatDoubleVertexInputFormat;
+import org.apache.giraph.lib.JsonLongDoubleFloatDoubleVertexOutputFormat;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Contains a simple unit test for {@link SimpleShortestPathsVertex}
+ */
+public class SimpleShortestPathsVertexTest {
+
+  /**
+   * Test the behavior when a shorter path to a vertex has been found
+   */
+  @Test
+  public void testOnShorterPathFound() throws Exception {
+
+    SimpleShortestPathsVertex vertex = new SimpleShortestPathsVertex();
+    vertex.initialize(null, null, null, null);
+    vertex.addEdge(new LongWritable(10L), new FloatWritable(2.5f));
+    vertex.addEdge(new LongWritable(20L), new FloatWritable(0.5f));
+
+    MockUtils.MockedEnvironment<LongWritable, DoubleWritable, FloatWritable,
+    DoubleWritable> env = MockUtils.prepareVertex(vertex, 1L,
+        new LongWritable(7L), new DoubleWritable(Double.MAX_VALUE),
+        false);
+
+    Mockito.when(env.getConfiguration().getLong(
+        SimpleShortestPathsVertex.SOURCE_ID,
+        SimpleShortestPathsVertex.SOURCE_ID_DEFAULT)).thenReturn(2L);
+
+    vertex.compute(Lists.newArrayList(new DoubleWritable(2),
+        new DoubleWritable(1.5)).iterator());
+
+    assertTrue(vertex.isHalted());
+    assertEquals(1.5, vertex.getVertexValue().get());
+
+    env.verifyMessageSent(new LongWritable(10L), new DoubleWritable(4));
+    env.verifyMessageSent(new LongWritable(20L), new DoubleWritable(2));
+  }
+
+  /**
+   * Test the behavior when a new, but not shorter path to a vertex has been
+   * found.
+   */
+  @Test
+  public void testOnNoShorterPathFound() throws Exception {
+
+    SimpleShortestPathsVertex vertex = new SimpleShortestPathsVertex();
+    vertex.initialize(null, null, null, null);
+    vertex.addEdge(new LongWritable(10L), new FloatWritable(2.5f));
+    vertex.addEdge(new LongWritable(20L), new FloatWritable(0.5f));
+
+    MockUtils.MockedEnvironment<LongWritable, DoubleWritable, FloatWritable,
+    DoubleWritable> env = MockUtils.prepareVertex(vertex, 1L,
+        new LongWritable(7L), new DoubleWritable(0.5), false);
+
+    Mockito.when(env.getConfiguration().getLong(
+        SimpleShortestPathsVertex.SOURCE_ID,
+        SimpleShortestPathsVertex.SOURCE_ID_DEFAULT)).thenReturn(2L);
+
+    vertex.compute(Lists.newArrayList(new DoubleWritable(2),
+        new DoubleWritable(1.5)).iterator());
+
+    assertTrue(vertex.isHalted());
+    assertEquals(0.5, vertex.getVertexValue().get());
+
+    env.verifyNoMessageSent();
+  }
+
+  /**
+   * A local integration test on toy data
+   */
+  @Test
+  public void testToyData() throws Exception {
+
+    // a small four vertex graph
+    String[] graph = new String[] {
+        "[1,0,[[2,1],[3,3]]]",
+        "[2,0,[[3,1],[4,10]]]",
+        "[3,0,[[4,2]]]",
+        "[4,0,[]]"
+    };
+
+    // start from vertex 1
+    Map<String, String> params = Maps.newHashMap();
+    params.put(SimpleShortestPathsVertex.SOURCE_ID, "1");
+
+    // run internally
+    Iterable<String> results = InternalVertexRunner.run(
+        SimpleShortestPathsVertex.class,
+        JsonLongDoubleFloatDoubleVertexInputFormat.class,
+        JsonLongDoubleFloatDoubleVertexOutputFormat.class,
+        params, graph);
+
+    Map<Long, Double> distances = parseDistances(results);
+
+    // verify results
+    assertNotNull(distances);
+    assertEquals(4, distances.size());
+    assertEquals(0.0, distances.get(1L));
+    assertEquals(1.0, distances.get(2L));
+    assertEquals(2.0, distances.get(3L));
+    assertEquals(4.0, distances.get(4L));
+  }
+
+  private Map<Long, Double> parseDistances(Iterable<String> results) {
+    Map<Long, Double> distances =
+        Maps.newHashMapWithExpectedSize(Iterables.size(results));
+    for (String line : results) {
+      try {
+        JSONArray jsonVertex = new JSONArray(line);
+        distances.put(jsonVertex.getLong(0), jsonVertex.getDouble(1));
+      } catch (JSONException e) {
+        throw new IllegalArgumentException(
+            "Couldn't get vertex from line " + line, e);
+      }
+    }
+    return distances;
+  }
+}