giraph-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edu...@apache.org
Subject [1/9] git commit: updated refs/heads/trunk to 8675c84
Date Mon, 08 Dec 2014 19:21:36 GMT
Repository: giraph
Updated Branches:
  refs/heads/trunk fda1bb382 -> 8675c84a8


http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/gui/js/valpanel.js
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/gui/js/valpanel.js
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/gui/js/valpanel.js
new file mode 100644
index 0000000..98da751
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/gui/js/valpanel.js
@@ -0,0 +1,430 @@
+/*
+ * ValidationPanel is a class that abstracts the message, vertex 
+ * and exception details. It has three view modes - compact, preview and expanded.
+ * @param {container, resizeCallback} options - Initialize panel with these options.
+ * @param options.validationPanelContainer - Container of the panel.
+ * @param {callback} options.resizeCallback - Called when manual resize of the panel is complete.
+ * @param {object} options.editor - Reference to the graph editor object.
+ */
+function ValidationPanel(options) {
+    // JSON object of the buttons appearing.
+    // The key, i.e. M, E, V are used in the compact mode
+    this.buttonData = {
+        'M' : {
+            fullName : 'Message Integrity',
+            clickHandler : this.showMessageViolations.bind(this)
+        },
+        'E' : {
+            fullName : 'Exceptions',
+            clickHandler : this.showExceptions.bind(this)
+        },
+        'V' : {
+            fullName : 'Vertex Integrity',
+            clickHandler : this.showVertexViolations.bind(this)
+        }
+    }
+
+    // Both in px
+    this.compactWidth = 60;
+    this.previewWidth = 170;
+    // This is in %
+    this.expandWidth = 55;
+    this.state = ValidationPanel.StateEnum.COMPACT;
+    this.container = options.container;
+    this.resizeCallback = options.resizeCallback;
+    this.debuggerServerRoot = options.debuggerServerRoot;
+    this.editor = options.editor;
+    // Which label is currently being shown
+    this.currentLabel = null;
+    
+    $(this.container).css('height', this.height + 'px')
+    // Make it resizable horizontally
+    $(this.container).resizable({ handles : 'e', minWidth : this.previewWidth,
+        stop: (function(event, ui) {
+            this.resizeCallback();
+        }).bind(this)
+    });
+    this.initElements();
+    this.compact();
+}
+
+ValidationPanel.StateEnum = {
+    COMPACT : 'compact',
+    PREVIEW : 'preview',
+    EXPAND : 'expand'
+}
+
+/*
+ * Deferred callbacks for capture scenario
+ */
+ValidationPanel.prototype.onCaptureVertex = function(done, fail) {
+    this.onCaptureVertex.done = done;
+    this.onCaptureVertex.fail = fail;
+}
+
+/*
+ * Creates HTML elements for valpanel.
+ */
+ValidationPanel.prototype.initElements = function() {
+    // Div to host the right arrow and close button on the top right.
+    var iconsContainer = $('<div />')
+                            .attr('class', 'valpanel-icons-container')
+                            .appendTo(this.container)
+
+    // Create a right-pointed arrow
+    this.rightArrow = $('<span />')
+        .attr('class', 'glyphicon glyphicon-circle-arrow-right')
+        .appendTo(iconsContainer);
+
+    // Create a close button - Clicking it will compact the panel.
+    this.btnClose = $('<span />')
+        .attr('class', 'glyphicon glyphicon-remove valpanel-btn-close')
+        .click((function() { 
+            this.compact(); 
+        }).bind(this))
+        .hide()
+        .appendTo(iconsContainer);
+
+    // Create all the buttons.
+    this.btnContainer = $('<ul />')
+        .attr('class', 'list-unstyled valpanel-btn-container')    
+        .appendTo(this.container);
+
+    // This is the container for the main content.
+    this.contentContainer = $('<div />')
+        .attr('class', 'valpanel-content-container')
+        .hide()
+        .appendTo(this.container);
+
+    // Preloader reference.
+    this.preloader = $('<div />')
+        .attr('class', 'valpanel-preloader')
+        .hide()
+        .appendTo(this.container);
+
+    for (var label in this.buttonData) {
+        var button = $('<button />')
+                        .attr('class', 'btn btn-success btn-valpanel')
+                        .attr('id', this.btnLabelToId(label))
+                        .attr('disabled', 'true')
+                        .click(this.buttonData[label]['clickHandler']);
+        var iconSpan = $('<span />')
+            .appendTo(button);
+        var textSpan = $("<span />")
+            .html(' ' + label)
+            .appendTo(button);
+        // Associate this physical button element with the cache entry.
+        this.buttonData[label].button = button;
+        this.buttonData[label].iconSpan = iconSpan;
+        this.buttonData[label].textSpan = textSpan;
+        $(this.btnContainer).append(
+            $("<li />").append(button)
+        );
+    }
+}
+
+ValidationPanel.prototype.btnLabelToId = function(label) {
+    return 'btn-valpanel-' + label;
+}
+
+/*
+ * Expands the width of the panel to show full names of each of the buttons.
+ */
+ValidationPanel.prototype.preview = function() {
+    if (!$(this.container).is(':animated')) {
+        // Set state to preview.
+        this.btnContainer.removeClass(this.state);
+        this.state = ValidationPanel.StateEnum.PREVIEW;
+        this.btnContainer.addClass(this.state);
+        $(this.btnClose).hide();
+        $(this.contentContainer).hide();
+        $(this.container).animate({ width: this.previewWidth + 'px'}, 300, 
+            (function() { 
+                this.resizeCallback(); 
+        }).bind(this));
+
+        // Expand names to full names 
+        for (var label in this.buttonData) {
+            var buttonData = this.buttonData[label];
+            $(buttonData.textSpan).html(buttonData.fullName);
+        }
+    }
+}
+
+/*
+ * Compacts the width of the panel to show only the labels of the buttons.
+ */
+ValidationPanel.prototype.compact = function() {
+    if (!$(this.container).is(':animated')) {
+        var prevState = this.state;
+        this.currentLabel = null;
+        this.state = ValidationPanel.StateEnum.COMPACT;
+        // Uncolor all editor nodes
+        this.editor.colorNodes([], null /* not required */, true);
+        $(this.btnClose).hide();
+        $(this.rightArrow).show();
+        $(this.contentContainer).hide();
+        $(this.container).animate({ width: this.compactWidth + 'px'}, 300,
+            (function() {
+                // Compact names to labels.
+                for (var label in this.buttonData) {
+                    var buttonData = this.buttonData[label];
+                    $(buttonData.textSpan).html(label);
+                }    
+                this.btnContainer.removeClass(prevState);
+                this.btnContainer.addClass(this.state);
+                this.resizeCallback(); 
+        }).bind(this));
+    }
+}
+
+ValidationPanel.prototype.expand = function() {
+    this.btnContainer.removeClass(this.state);
+    this.state = ValidationPanel.StateEnum.EXPAND;
+    this.btnContainer.addClass(this.state);
+    // Show close button, hide right arrow, show content.
+    $(this.btnClose).show();
+    $(this.rightArrow).hide();
+    $(this.container).animate({ width: this.expandWidth + '%'}, 500,
+        (function() {
+            $(this.contentContainer).show('slow');
+            this.resizeCallback();
+        }).bind(this));
+}
+
+/*
+ * Fetch the message integrity violations from the debugger server
+ * and construct a table to show the data.
+ */
+ValidationPanel.prototype.showMessageViolations = function() {
+    this.expand();
+    this.currentLabel = 'M';
+    // Empty the content container and add violations table.
+    this.contentContainer.empty();
+    // The data should already be present in the buttonData cache.
+    var data = this.buttonData[this.currentLabel].data;
+    var table = $("<table />")
+        .attr('class', 'table')
+        .attr('id', 'valpanel-M-table')
+        .html('<thead><tr><th>Source ID</th><th>Destination
ID</th><th>Message</th><th></th></tr></thead>')
+        .appendTo(this.contentContainer);
+
+    var btnCaptureScenario = 
+        $('<button type="button" class="btn btn-sm btn-primary btn-vp-M-capture">Capture
Scenario</button>');
+
+    var dataTable = $(table).DataTable({
+        'columns' : [
+            { 'data' : 'srcId' },
+            { 'data' : 'destinationId' },
+            { 'data' : 'message' },
+            {
+                'orderable' : false,
+                'data' : null,
+                'defaultContent' : $(btnCaptureScenario).prop('outerHTML')
+            },
+        ]
+    });
+    if (data) {
+        for (var taskId in data) {
+            var violations = data[taskId].violations;
+            for (var i = 0; violations && i < violations.length; ++i) {
+                var violation = violations[i];
+                violation.superstepId = this.superstepId;
+                dataTable.row.add(violation).draw();
+            }
+        }
+    }
+    // Attach click event to the capture Scenario button.
+    $('button.btn-vp-M-capture').click((function(event) {
+        var tr = $(event.target).parents('tr');
+        var row = dataTable.row(tr);
+        var data = row.data();
+        Utils.fetchVertexTest(this.debuggerServerRoot, this.jobId, 
+            this.superstepId, data.srcId, 'msg')
+        .done((function(response) {
+            this.onCaptureVertex.done(response);
+        }).bind(this))
+        .fail((function(response) {
+            this.onCaptureVertex.fail(response.responseText);
+        }).bind(this))
+    }).bind(this));
+}
+
+/*
+ * Fetch vertex value violations from the server and
+ * construct a table to show the data.
+ */
+ValidationPanel.prototype.showVertexViolations = function() {
+    this.expand();
+    this.currentLabel = 'V';
+    var data = this.buttonData[this.currentLabel].data;
+    // Empty the content container and add violations table.
+    this.contentContainer.empty();
+    var table = $("<table />")
+        .attr('class', 'table')
+        .attr('id', 'valpanel-V-table')
+        .html('<thead><tr><th>Vertex ID</th><th>Vertex Value</th><th></th></tr></thead>')
+        .appendTo(this.contentContainer);
+
+    var btnCaptureScenario = 
+        $('<button type="button" class="btn btn-sm btn-primary btn-vp-V-capture">Capture
Scenario</button>');
+
+    var dataTable = $(table).DataTable({
+        'columns' : [
+            { 'data' : 'vertexId' },
+            { 'data' : 'vertexValue' },
+            {
+                'orderable' : false,
+                'data' : null,
+                'defaultContent' : $(btnCaptureScenario).prop('outerHTML')
+            },
+        ]
+    });
+    var violationIds = [];
+    if (data) {
+        for (var vertexId in data) {
+            var violation = data[vertexId];
+            violation.superstepId = this.superstepId;
+            dataTable.row.add(violation).draw();
+            violationIds.push(vertexId);
+        }
+    }
+    // Attach click event to the capture Scenario button.
+    $('button.btn-vp-V-capture').click((function(event) {
+        var tr = $(event.target).parents('tr');
+        var row = dataTable.row(tr);
+        var data = row.data(); 
+        Utils.fetchVertexTest(this.debuggerServerRoot, this.jobId, 
+            this.superstepId, data.vertexId, 'vv')
+        .done((function(response) {
+            this.onCaptureVertex.done(response);
+        }).bind(this))
+        .fail((function(response) {
+            this.onCaptureVertex.fail(response.responseText);
+        }).bind(this))
+    }).bind(this));
+    // Color the vertices with violations
+    this.editor.colorNodes(violationIds, this.editor.errorColor, true);
+}
+
+/*
+ * Show exceptions for this superstep.
+ */
+ValidationPanel.prototype.showExceptions = function() {
+    this.expand();
+    this.currentLabel = 'E';
+    var data = this.buttonData[this.currentLabel].data;
+    // Empty the content container and add violations table.
+    // TODO(vikesh) Master exceptions.
+    this.contentContainer.empty();
+    var table = $("<table />")
+        .attr('class', 'table')
+        .attr('id', 'valpanel-V-table')
+        .html('<thead><tr><th>Vertex ID</th><th>Message</th><th>Stack
Trace</th><th></th></tr></thead>')
+        .appendTo(this.contentContainer);
+
+    var btnCaptureScenario = 
+        $('<button type="button" class="btn btn-sm btn-primary btn-vp-E-capture">Capture
Scenario</button>');
+
+    var dataTable = $(table).DataTable({
+        'columns' : [
+            { 'data' : 'vertexId' },
+            { 'data' : 'exception.message' },
+            { 'data' : 'exception.stackTrace' },
+            {
+                'orderable' : false,
+                'data' : null,
+                'defaultContent' : $(btnCaptureScenario).prop('outerHTML')
+            }
+        ]
+    });
+    var violationIds = [];
+    if (data) {
+        for (var vertexId in data) {
+            var violation = data[vertexId];
+            violation.superstepId = this.superstepId;
+            dataTable.row.add(violation).draw();
+            violationIds.push(vertexId);
+        }
+    }
+    // Attach click event to the capture Scenario button.
+    $('button.btn-vp-E-capture').click((function(event) {
+        var tr = $(event.target).parents('tr');
+        var row = dataTable.row(tr);
+        var data = row.data(); 
+        Utils.fetchVertexTest(this.debuggerServerRoot, this.jobId, 
+            this.superstepId, data.vertexId, 'err')
+        .done((function(response) {
+            this.onCaptureVertex.done(response);
+        }).bind(this))
+        .fail((function(response) {
+            this.onCaptureVertex.fail(response.responseText);
+        }).bind(this))
+    }).bind(this));
+    // Color the nodes with exception.
+    this.editor.colorNodes(violationIds, this.editor.errorColor, true);
+}
+
+/*
+ * Handle the received data from the debugger server.
+ */
+ValidationPanel.prototype.onReceiveData = function(buttonType) {
+    return (function(response) {
+        // Data is set here. The click handlers will simply use this data.
+        this.buttonData[buttonType].data = response;
+        this.buttonData[buttonType].button.attr('disabled', false);
+        // No violations.
+        if($.isEmptyObject(response)) {
+            this.buttonData[buttonType].button.addClass('btn-success');
+            this.buttonData[buttonType].button.removeClass('btn-danger');
+        } else {
+            this.buttonData[buttonType].button.addClass('btn-danger');
+            this.buttonData[buttonType].button.removeClass('btn-success');
+        }
+        // If this is the currently selected label, update the contents.
+        if (buttonType === this.currentLabel) {
+            this.buttonData[buttonType].clickHandler(); 
+        }
+    }).bind(this);
+}
+
+/*
+ * Sets the current jobId and superstepId. Expected to called by the 
+ * orchestrator (debugger.js) while stepping through the job.
+ * @param {jobId, superstepId} data
+ * @param data.jobId - Current jobId
+ * @param data.superstepId - Current superstepId
+ */
+ValidationPanel.prototype.setData = function(jobId, superstepId) {
+    this.jobId = jobId;
+    this.superstepId = superstepId;
+
+    // setData makes AJAX calls to the debugger server for each button type
+    for (var type in this.buttonData) {
+        // Disable all buttons to begin with
+        this.buttonData[type].button.attr('disabled', true);
+        $.ajax({
+                url: this.debuggerServerRoot + '/integrity',
+                data: {'jobId' : this.jobId, 'superstepId' : this.superstepId, 'type' : type}
+        })
+        .retry({
+                times: 3,
+                timeout: 1000,
+        })
+        .done(this.onReceiveData(type))
+        .fail((function(buttonLabel) {
+                return function(response) {
+                    noty({text : 'Failed to fetch data for ' + buttonLabel + 
+                                '. Please check your network and debugger server.', type
: 'error'});
+                }
+            })(this.buttonData[type].fullName))
+        }
+}
+
+ValidationPanel.prototype.showPreloader = function() {
+    this.preloader.show('slow');
+}
+
+ValidationPanel.prototype.hidePreloader = function() {
+    this.preloader.hide('slow');
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeSetUpFuncTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeSetUpFuncTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeSetUpFuncTemplate.vm
new file mode 100644
index 0000000..4ac8e1f
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeSetUpFuncTemplate.vm
@@ -0,0 +1,14 @@
+  @Before
+  public void setUp() throws Exception {
+    GiraphConfiguration config = new GiraphConfiguration();
+    config.setComputationClass($classUnderTestName#[[.class]]#);
+    GiraphConfiguration.VERTEX_ID_CLASS.set(config, $vertexIdType#[[.class]]#);
+    GiraphConfiguration.VERTEX_VALUE_CLASS.set(config, $vertexValueType#[[.class]]#);
+    GiraphConfiguration.EDGE_VALUE_CLASS.set(config, $edgeValueType#[[.class]]#);
+    GiraphConfiguration.INCOMING_MESSAGE_VALUE_CLASS.set(config, $inMsgType#[[.class]]#);
+    GiraphConfiguration.OUTGOING_MESSAGE_VALUE_CLASS.set(config, $outMsgType#[[.class]]#);
+#foreach( $config in $configs )
+    config.set#evaluate($config.classStr)("$config.key", $helper.format($config.value));
+#end
+    conf = new ImmutableClassesGiraphConfiguration<>(config);
+  }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestFuncTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestFuncTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestFuncTemplate.vm
new file mode 100644
index 0000000..3b3db4b
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestFuncTemplate.vm
@@ -0,0 +1,55 @@
+  @Test
+  public final void testCompute() {
+    try {
+      $classUnderTestName classUnderTest = ($classUnderTestName) conf.createComputation();
+
+      GraphState graphState = mock(GraphState.class);
+      when(graphState.getSuperstep()).thenReturn($superstepNo#[[l]]#);
+      when(graphState.getTotalNumVertices()).thenReturn($nVertices#[[l]]#);
+      when(graphState.getTotalNumEdges()).thenReturn($nEdges#[[l]]#);
+	
+      WorkerClientRequestProcessor<$vertexIdType, $vertexValueType, $edgeValueType>
processor = 
+          mock(WorkerClientRequestProcessor.class);
+	
+      WorkerAggregatorUsage aggr = mock(WorkerAggregatorUsage.class);
+#foreach ($aggr in $aggregators)
+      when(aggr.getAggregatedValue("$aggr.key")).thenReturn($helper.formatWritable($aggr.value));
+#end
+
+      classUnderTest.initialize(graphState, processor, null, aggr, null);
+    
+      Vertex<$vertexIdType, $vertexValueType, $edgeValueType> vertex = conf.createVertex();
+      vertex.initialize($helper.formatWritable($vertexId), $helper.formatWritable($vertexValue));
+      
+#if ($neighbors)
+      ReusableEdge<$vertexIdType, $edgeValueType> edge = conf.createReusableEdge();
+#foreach ($neighbor in $neighbors)
+      edge.setTargetVertexId($helper.formatWritable($neighbor.NbrId));
+#if ($neighbor.edgeValue)
+      edge.setValue($helper.formatWritable($neighbor.edgeValue));
+#end
+      vertex.addEdge(edge);
+#end
+#end
+
+      ArrayList<$inMsgType> inMsgs = new ArrayList<>();
+#foreach ($inMsg in $inMsgs)
+      inMsgs.add($helper.formatWritable($inMsg));   
+#end
+
+      classUnderTest.compute(vertex, inMsgs);
+
+#if ($vertexValueAfter)
+      // assertEquals($vertexValueAfter, vertex.getValue().get(), 0.001f);
+#end
+
+      // verifyZeroInteractions(processor);
+
+#foreach ($outMsg in $outMsgs)
+      // verify(processor, times($outMsg.times)).sendMessageRequest($helper.formatWritable($outMsg.msg.destinationId),
$helper.formatWritable($outMsg.msg.Message));
+#end
+      
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestTemplate.vm
new file mode 100644
index 0000000..e4b68e0
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ComputeTestTemplate.vm
@@ -0,0 +1,41 @@
+#if ($package)
+package $package;
+#end
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.giraph.comm.WorkerClientRequestProcessor;
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
+import org.apache.giraph.edge.ReusableEdge;
+import org.apache.giraph.graph.GraphState;
+import org.apache.giraph.graph.Vertex;
+import org.apache.giraph.utils.WritableUtils;
+import org.apache.giraph.worker.WorkerAggregatorUsage;
+import org.junit.Before;
+import org.junit.Test;
+
+import $classUnderTestFullName;
+#if ($usedTypes)
+#foreach ($type in $usedTypes)
+import $type.Name;
+#end
+#end
+
+public class $className {
+
+  private ImmutableClassesGiraphConfiguration<$vertexIdType, $vertexValueType, $edgeValueType>
conf;
+
+#parse("ComputeTestFuncTemplate.vm")
+
+
+#parse("ComputeSetUpFuncTemplate.vm")
+
+
+#parse("ReadWritableFromByteArrayTemplate.vm")
+
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/MasterComputeTestTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/MasterComputeTestTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/MasterComputeTestTemplate.vm
new file mode 100644
index 0000000..723fc97
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/MasterComputeTestTemplate.vm
@@ -0,0 +1,57 @@
+#if ($package)
+package $package;
+#end
+
+import static org.mockito.Mockito.*;
+
+import org.junit.Test;
+import org.apache.giraph.conf.GiraphConfiguration;
+import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
+import org.apache.giraph.graph.GraphState;
+import org.apache.giraph.bsp.CentralizedServiceMaster;
+import org.apache.giraph.master.MasterAggregatorHandler;
+
+import $classUnderTestFullName;
+#if ($usedTypesByAggregators)
+#foreach ($type in $usedTypesByAggregators)
+import $type.Name;
+#end
+#end
+
+public class $className {
+
+  @Test
+  public void test() {
+    GiraphConfiguration config = new GiraphConfiguration();
+    config.setMasterComputeClass($classUnderTestName#[[.class]]#);
+    setupConfiguration(config);
+    ImmutableClassesGiraphConfiguration conf = new ImmutableClassesGiraphConfiguration<>(config);
+
+    $classUnderTestName classUnderTest = ($classUnderTestName) conf.createMasterCompute();
+
+    GraphState graphState = mock(GraphState.class);
+    when(graphState.getSuperstep()).thenReturn($superstepNo#[[l]]#);
+    when(graphState.getTotalNumVertices()).thenReturn($nVertices#[[l]]#);
+    when(graphState.getTotalNumEdges()).thenReturn($nEdges#[[l]]#);
+    classUnderTest.setGraphState(graphState);
+
+    MasterAggregatorHandler aggregatorHandler = mock(MasterAggregatorHandler.class);
+#foreach ($aggr in $aggregators)
+    when(aggregatorHandler.getAggregatedValue("$aggr.key")).thenReturn($helper.formatWritable($aggr.value));
+#end
+    CentralizedServiceMaster serviceMaster = mock(CentralizedServiceMaster.class);
+    when(serviceMaster.getAggregatorHandler()).thenReturn(aggregatorHandler);
+    classUnderTest.setMasterService(serviceMaster);
+
+    classUnderTest.compute();
+  }
+  
+  
+  #parse("ReadWritableFromStringTemplate.vm")
+
+  public void setupConfiguration(GiraphConfiguration config) {
+#foreach( $config in $configs )
+    config.set#evaluate($config.classStr)("$config.key", $helper.format($config.value));
+#end
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromByteArrayTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromByteArrayTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromByteArrayTemplate.vm
new file mode 100644
index 0000000..bc67347
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromByteArrayTemplate.vm
@@ -0,0 +1,16 @@
+#if ($complexWritables)
+#foreach ($class in $complexWritables)
+#set ($writableClassName = $class.simpleName)
+  private $writableClassName read$writableClassName#[[FromByteArray]]#(byte[] byteArray)
{
+    $writableClassName writable = null;
+    try {
+      writable = $writableClassName#[[.class.newInstance();]]#
+    } catch (InstantiationException | IllegalAccessException e) {
+      e.printStackTrace();
+    }
+    WritableUtils.readFieldsFromByteArray(byteArray, writable);
+    return writable;
+  }
+  
+#end
+#end
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromStringTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromStringTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromStringTemplate.vm
new file mode 100644
index 0000000..dcf2ada
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/ReadWritableFromStringTemplate.vm
@@ -0,0 +1,16 @@
+#if ($complexWritables)
+#foreach ($class in $complexWritables)
+#set ($writableClassName = $class.simpleName)
+  private $writableClassName read$writableClassName#[[FromString]]#(String str) {
+    $writableClassName writable = null;
+    try {
+      writable = $writableClassName#[[.class.newInstance();]]#
+    } catch (InstantiationException | IllegalAccessException e) {
+      e.printStackTrace();
+    }
+    WritableUtils.readFieldsFromByteArray(str.getBytes(), writable);
+    return writable;
+  }
+  
+#end
+#end
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/TestGraphTemplate.vm
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/TestGraphTemplate.vm
b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/TestGraphTemplate.vm
new file mode 100644
index 0000000..a97a031
--- /dev/null
+++ b/giraph-debugger/src/main/resources/org/apache/giraph/debugger/mock/TestGraphTemplate.vm
@@ -0,0 +1,10 @@
+    TestGraph<$vertexIdClass, $vertexValueClass, $edgeValueClass> graph 
+         = new TestGraph<>(new GiraphConfiguration());
+    graph      
+#foreach ($vertex in $vertices)
+    .addVertex($helper.formatWritable($vertex.id), $helper.formatWritable($vertex.value))
+#foreach ($neighbor in $vertex.neighbors)
+    .addEdge($helper.formatWritable($vertex.id), $helper.formatWritable($neighbor.id), $helper.formatWritable($neighbor.edgeValue))
+#end 
+#end
+    ;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/BaseComputation.java
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/BaseComputation.java
b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/BaseComputation.java
new file mode 100644
index 0000000..b8f9d1a
--- /dev/null
+++ b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/BaseComputation.java
@@ -0,0 +1,61 @@
+/*
+ * 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.debugger.instrumenter.test.basecompute;
+
+import java.io.IOException;
+
+import org.apache.giraph.graph.BasicComputation;
+import org.apache.giraph.graph.Vertex;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+
+/**
+ * TODO(semih, jaeho): What's this class used for?
+ */
+public abstract class BaseComputation extends BasicComputation<LongWritable,
+  DoubleWritable, FloatWritable, DoubleWritable> {
+
+  @Override
+  public final void compute(
+    Vertex<LongWritable, DoubleWritable, FloatWritable> vertex,
+    Iterable<DoubleWritable> messages) throws IOException {
+    collect(vertex, messages);
+    signal(vertex, messages);
+    vertex.voteToHalt();
+  }
+
+  /**
+   * TODO(semih, jaeho): Fill in.
+   * @param vertex
+   * @param messages
+   */
+  protected abstract void signal(
+    Vertex<LongWritable, DoubleWritable, FloatWritable> vertex,
+    Iterable<DoubleWritable> messages);
+
+  /**
+   * TODO(semih, jaeho): Fill in.
+   * @param vertex
+   * @param messages
+   */
+  protected abstract void collect(
+    Vertex<LongWritable, DoubleWritable, FloatWritable> vertex,
+    Iterable<DoubleWritable> messages);
+
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/CommonDebugConfig.java
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/CommonDebugConfig.java
b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/CommonDebugConfig.java
new file mode 100644
index 0000000..7e55727
--- /dev/null
+++ b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/CommonDebugConfig.java
@@ -0,0 +1,36 @@
+/*
+ * 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.debugger.instrumenter.test.basecompute;
+
+import org.apache.giraph.debugger.DebugConfig;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+
+/**
+ * TODO(semih, jaeho): What's this class used for?
+ */
+public class CommonDebugConfig extends DebugConfig<LongWritable,
+  DoubleWritable, FloatWritable, DoubleWritable, DoubleWritable> {
+
+  @Override
+  public boolean shouldCatchExceptions() {
+    return true;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/DerivedComputation.java
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/DerivedComputation.java
b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/DerivedComputation.java
new file mode 100644
index 0000000..78e8f4c
--- /dev/null
+++ b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/DerivedComputation.java
@@ -0,0 +1,99 @@
+/*
+ * 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.debugger.instrumenter.test.basecompute;
+
+import org.apache.giraph.conf.LongConfOption;
+import org.apache.giraph.edge.Edge;
+import org.apache.giraph.graph.BasicComputation;
+import org.apache.giraph.graph.Vertex;
+import org.apache.hadoop.io.DoubleWritable;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.log4j.Logger;
+
+/**
+ * TODO(semih, jaeho): What's this class used for?
+ */
+public class DerivedComputation extends BaseComputation {
+
+  /**
+   * The shortest paths id.
+   */
+  public static final LongConfOption SOURCE_ID = new LongConfOption(
+    "SimpleShortestPathsVertex.sourceId", 1, "The shortest paths id");
+
+  /**
+   * Class logger.
+   */
+  private static final Logger LOG = Logger.getLogger(BasicComputation.class);
+
+  /**
+   * Minimum distance found so far. Kept as a global variable for efficiency.
+   */
+  private double minDist;
+
+  @Override
+  protected void collect(
+    Vertex<LongWritable, DoubleWritable, FloatWritable> vertex,
+    Iterable<DoubleWritable> messages) {
+    if (getSuperstep() == 0) {
+      vertex.setValue(new DoubleWritable(Double.MAX_VALUE));
+    }
+    if (getSuperstep() == 8) {
+      throw new RuntimeException("bug");
+    }
+    minDist = isSource(vertex) ? 0d : Double.MAX_VALUE;
+    for (DoubleWritable message : messages) {
+      minDist = Math.min(minDist, message.get());
+    }
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Vertex " + vertex.getId() + " got minDist = " + minDist +
+        " vertex value = " + vertex.getValue());
+    }
+  }
+
+  @Override
+  protected void signal(
+    Vertex<LongWritable, DoubleWritable, FloatWritable> vertex,
+    Iterable<DoubleWritable> messages) {
+    if (minDist < vertex.getValue().get()) {
+      vertex.setValue(new DoubleWritable(minDist));
+      for (Edge<LongWritable, FloatWritable> edge : vertex.getEdges()) {
+        double distance = minDist + edge.getValue().get();
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Vertex " + vertex.getId() + " sent to " +
+            edge.getTargetVertexId() + " = " + distance);
+        }
+        // INTENTIONAL BUG:Instead of sending the distance (i.e. by
+        // adding edge values), we send the vertex value.
+        sendMessage(edge.getTargetVertexId(), new DoubleWritable(minDist));
+      }
+    }
+  }
+
+  /**
+   * Is this vertex the source id?
+   *
+   * @param vertex
+   *          Vertex
+   * @return True if the source id
+   */
+  private boolean isSource(Vertex<LongWritable, ?, ?> vertex) {
+    return vertex.getId().get() == SOURCE_ID.get(getConf());
+  }
+}

http://git-wip-us.apache.org/repos/asf/giraph/blob/8675c84a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/package-info.java
----------------------------------------------------------------------
diff --git a/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/package-info.java
b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/package-info.java
new file mode 100644
index 0000000..fac388c
--- /dev/null
+++ b/giraph-debugger/src/test/java/org/apache/giraph/debugger/instrumenter/test/basecompute/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * Some tests for Graft instrumenter.
+ */
+package org.apache.giraph.debugger.instrumenter.test.basecompute;


Mime
View raw message