You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by ph...@apache.org on 2010/08/05 02:07:25 UTC

svn commit: r982434 [2/2] - in /avro/trunk: ./ lang/java/src/java/org/apache/avro/ipc/ lang/java/src/java/org/apache/avro/ipc/trace/ lang/java/src/test/java/org/apache/avro/ipc/trace/ share/schemas/org/apache/avro/ipc/trace/

Added: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java?rev=982434&view=auto
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java (added)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestSpanTraceFormation.java Thu Aug  5 00:07:24 2010
@@ -0,0 +1,279 @@
+/**
+ * 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.avro.ipc.trace;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.avro.Schema;
+import org.apache.avro.generic.GenericData;
+import org.apache.avro.util.Utf8;
+import org.junit.Test;
+
+public class TestSpanTraceFormation {
+  
+  @Test
+  public void testSpanEquality() {
+    Span root = new Span();
+    root.spanID = Util.idValue(10);
+    root.parentSpanID = null;
+    root.messageName = new Utf8("startCall");
+    
+    Span a = new Span();
+    a.spanID = Util.idValue(11);
+    a.parentSpanID = Util.idValue(10);
+    a.messageName = new Utf8("childCall1");
+    
+    Span b = new Span();
+    b.spanID = Util.idValue(12);
+    b.parentSpanID = Util.idValue(10);
+    b.messageName = new Utf8("childCall2");
+    
+    Span c = new Span();
+    c.spanID = Util.idValue(13);
+    c.parentSpanID = Util.idValue(10);
+    c.messageName = new Utf8("childCall3");
+    
+    List<Span> spans = new LinkedList<Span>();
+    spans.add(root);
+    spans.add(a);
+    spans.add(b);
+    spans.add(c);
+    Trace trace1 = Trace.extractTrace(spans);
+    
+    Span d = new Span();
+    d.spanID = Util.idValue(11);
+    d.parentSpanID = Util.idValue(10);
+    d.messageName = new Utf8("childCall1");
+    
+    Span e = new Span();
+    e.spanID = Util.idValue(12);
+    e.parentSpanID = Util.idValue(10);
+    e.messageName = new Utf8("childCall2");
+    
+    Span f = new Span();
+    f.spanID = Util.idValue(13);
+    f.parentSpanID = Util.idValue(10);
+    f.messageName = new Utf8("childCall3");
+    
+    spans.clear();
+    spans.add(d);
+    spans.add(e);
+    spans.add(f);
+    spans.add(root);
+    Trace trace2 = Trace.extractTrace(spans);
+    
+    assertEquals(trace1.executionPathHash(), trace2.executionPathHash());
+  }
+  
+  
+  @Test
+  public void testSpanEquality2() {
+    Span root = new Span();
+    root.spanID = Util.idValue(10);
+    root.parentSpanID = null;
+    root.messageName = new Utf8("startCall");
+    
+    Span a = new Span();
+    a.spanID = Util.idValue(11);
+    a.parentSpanID = Util.idValue(10);
+    a.messageName = new Utf8("childCall1");
+    
+    Span b = new Span();
+    b.spanID = Util.idValue(12);
+    b.parentSpanID = Util.idValue(10);
+    b.messageName = new Utf8("childCall2");
+    
+    Span c = new Span();
+    c.spanID = Util.idValue(13);
+    c.parentSpanID = Util.idValue(10);
+    c.messageName = new Utf8("childCall3");
+    
+    List<Span> spans = new LinkedList<Span>();
+    spans.add(root);
+    spans.add(a);
+    spans.add(b);
+    spans.add(c);
+    Trace trace1 = Trace.extractTrace(spans);
+    
+    Span d = new Span();
+    d.spanID = Util.idValue(11);
+    d.parentSpanID = Util.idValue(10);
+    d.messageName = new Utf8("childCall1");
+    
+    Span e = new Span();
+    e.spanID = Util.idValue(12);
+    e.parentSpanID = Util.idValue(10);
+    e.messageName = new Utf8("childCall2");
+    
+    Span f = new Span();
+    f.spanID = Util.idValue(13);
+    f.parentSpanID = Util.idValue(10);
+    f.messageName = new Utf8("childCall3");
+    
+    Span g = new Span();
+    g.spanID = Util.idValue(14);
+    g.parentSpanID = Util.idValue(13);
+    g.messageName = new Utf8("childCall4");
+    
+    spans.clear();
+    spans.add(d);
+    spans.add(e);
+    spans.add(f);
+    spans.add(g);
+    spans.add(root);
+    Trace trace2 = Trace.extractTrace(spans);
+    
+    assertFalse(trace1.executionPathHash() == trace2.executionPathHash());
+  }
+  
+  /** Create a span with bogus timing events. */
+  public static Span createFullSpan(Long id, Long parentID, String messageName) {
+    Span out = new Span();
+    out.spanID = Util.idValue(id);
+    if (parentID != null) {
+      out.parentSpanID = Util.idValue(parentID);
+    }
+    out.messageName = new Utf8(messageName);
+    
+    out.events = new GenericData.Array<TimestampedEvent>(
+        4, Schema.createArray(TimestampedEvent.SCHEMA$));
+    
+    for (SpanEvent ev: SpanEvent.values()) {
+      TimestampedEvent newEvent = new TimestampedEvent();
+      newEvent.timeStamp = System.currentTimeMillis() * 1000000;
+      newEvent.event = ev;
+      out.events.add(newEvent);
+    }
+    
+    out.complete = true;
+    
+    return out;
+  }
+  
+  /**
+   * Describe this trace with two different orderings and make sure
+   * they equate to being equal. 
+   * 
+   *    b
+   *   / 
+   *  a -b    g-i
+   *   \     /
+   *    d-e-f
+   *        \
+   *         g-i
+   */
+ 
+  @Test
+  public void testSpanEquality3() {
+    
+    Span a = createFullSpan((long) 1, null, "a");
+    Span b1 = createFullSpan((long) 2, (long) 1, "b");
+    Span b2 = createFullSpan((long) 3, (long) 1, "b");
+    Span d = createFullSpan((long) 4, (long) 1, "d");
+    Span e = createFullSpan((long) 5, (long) 4, "e");
+    Span f = createFullSpan((long) 6, (long) 5, "f");
+    Span g1 = createFullSpan((long) 7, (long) 6, "g");
+    Span g2 = createFullSpan((long) 8, (long) 6, "g");
+    Span i1 = createFullSpan((long) 9, (long) 7, "i");
+    Span i2 = createFullSpan((long) 10, (long) 8, "i");
+    
+    List<Span> spans = new LinkedList<Span>();
+    spans.addAll(Arrays.asList(new Span[] {a, b1, b2, d, e, f, g1, g2, i1, i2}));
+    Trace trace1 = Trace.extractTrace(spans);
+    
+    // Re-order and make sure still equivalent
+    spans.clear();
+    spans.addAll(Arrays.asList(new Span[] {i2, b1, g1, e, f, d, b2, g2, i1, a}));
+    Trace trace2 = Trace.extractTrace(spans);
+    assertNotNull(trace1);
+    assertNotNull(trace2);
+    assertEquals(trace1.executionPathHash(), trace2.executionPathHash());
+    assertEquals(trace1.executionPathHash(), trace2.executionPathHash());
+    
+    // Remove a span and make sure not equivalent
+    spans.clear();
+    spans.addAll(Arrays.asList(new Span[] {i2, b1, g1, e, f, d, b2, g2, a}));
+    Trace trace3 = Trace.extractTrace(spans);
+    assertNotNull(trace3);
+    assertTrue(trace1.executionPathHash() == trace2.executionPathHash());
+    assertTrue(trace1.executionPathHash() != trace3.executionPathHash());
+    assertTrue(trace2.executionPathHash() != trace3.executionPathHash());
+  }
+  
+  @Test
+  public void testBasicTraceFormation() {
+    Span root = new Span();
+    root.spanID = Util.idValue(10);
+    root.parentSpanID = null;
+    root.messageName = new Utf8("startCall");
+    
+    Span a = new Span();
+    a.spanID = Util.idValue(11);
+    a.parentSpanID = Util.idValue(10);
+    a.messageName = new Utf8("childCall1");
+    
+    Span b = new Span();
+    b.spanID = Util.idValue(12);
+    b.parentSpanID = Util.idValue(10);
+    b.messageName = new Utf8("childCall2");
+    
+    Span c = new Span();
+    c.spanID = Util.idValue(13);
+    c.parentSpanID = Util.idValue(10);
+    c.messageName = new Utf8("childCall3");
+    
+    List<Span> spans = new LinkedList<Span>();
+    spans.add(root);
+    spans.add(a);
+    spans.add(b);
+    spans.add(c);
+    Trace trace = Trace.extractTrace(spans);
+    
+    assertNotNull(trace);
+    
+    TraceNode rootNode = trace.getRoot();
+    assertEquals(rootNode.span.messageName, new Utf8("startCall"));
+    assertEquals(3, rootNode.children.size());
+    boolean found1, found2, found3;
+    found1 = found2 = found3 = false;
+    
+    for (TraceNode tn: rootNode.children) {
+      if (tn.span.messageName.equals(new Utf8("childCall1"))) {
+        found1 = true;
+      }
+      if (tn.span.messageName.equals(new Utf8("childCall2"))) {
+        found2 = true;
+      }
+      if (tn.span.messageName.equals(new Utf8("childCall3"))) {
+        found3 = true;
+      }
+      assertNotNull(tn.children);
+      assertEquals(0, tn.children.size());
+    }
+    assertTrue(found1);
+    assertTrue(found2);
+    assertTrue(found3);
+   }
+ }

Added: avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl
URL: http://svn.apache.org/viewvc/avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl?rev=982434&view=auto
==============================================================================
--- avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl (added)
+++ avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avdl Thu Aug  5 00:07:24 2010
@@ -0,0 +1,37 @@
+/**
+ * A Span is our basic unit of tracing. It tracks the critical points
+ * of a single RPC call and records other call meta-data. It also
+ * allows arbitrary string annotations. Both the client and server create
+ * Span objects, each of which is populated with half of the relevant event
+ * data. They share a span ID, which allows us to merge them into one complete
+ * span later on.
+ */
+@namespace("org.apache.avro.ipc.trace")
+
+protocol AvroTrace {
+  enum SpanEvent { SERVER_RECV, SERVER_SEND, CLIENT_RECV, CLIENT_SEND }
+
+  fixed ID(8);
+
+  record TimestampedEvent {
+    long timeStamp; // Unix time, in nanoseconds
+    union { SpanEvent, string} event;
+  }
+
+  record Span {
+    ID  traceID;  // ID shared by all Spans in a given trace
+    ID spanID;    // Random ID for this Span
+    union { ID, null } parentSpanID; // Parent Span ID (null if root Span)
+    string messageName;       // Function call represented
+    long requestPayloadSize;  // Size (bytes) of the request
+    long responsePayloadSize; // Size (byts) of the response
+    union { string, null} requestorHostname; // Hostname of requestor
+//    int requestorPort;     // Port of the requestor (currently unused)
+    union { string, null } responderHostname; // Hostname of the responder
+//    int responderPort;     // Port of the responder (currently unused)
+    array<TimestampedEvent> events;  // List of critical events
+    boolean complete; // Whether includes data from both sides
+  }
+
+  array<Span> getAllSpans();
+}

Added: avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr
URL: http://svn.apache.org/viewvc/avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr?rev=982434&view=auto
==============================================================================
--- avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr (added)
+++ avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr Thu Aug  5 00:07:24 2010
@@ -0,0 +1,69 @@
+{
+  "protocol" : "AvroTrace",
+  "namespace" : "org.apache.avro.ipc.trace",
+  "types" : [ {
+    "type" : "enum",
+    "name" : "SpanEvent",
+    "symbols" : [ "SERVER_RECV", "SERVER_SEND", "CLIENT_RECV", "CLIENT_SEND" ]
+  }, {
+    "type" : "fixed",
+    "name" : "ID",
+    "size" : 8
+  }, {
+    "type" : "record",
+    "name" : "TimestampedEvent",
+    "fields" : [ {
+      "name" : "timeStamp",
+      "type" : "long"
+    }, {
+      "name" : "event",
+      "type" : [ "SpanEvent", "string" ]
+    } ]
+  }, {
+    "type" : "record",
+    "name" : "Span",
+    "fields" : [ {
+      "name" : "traceID",
+      "type" : "ID"
+    }, {
+      "name" : "spanID",
+      "type" : "ID"
+    }, {
+      "name" : "parentSpanID",
+      "type" : [ "ID", "null" ]
+    }, {
+      "name" : "messageName",
+      "type" : "string"
+    }, {
+      "name" : "requestPayloadSize",
+      "type" : "long"
+    }, {
+      "name" : "responsePayloadSize",
+      "type" : "long"
+    }, {
+      "name" : "requestorHostname",
+      "type" : [ "string", "null" ]
+    }, {
+      "name" : "responderHostname",
+      "type" : [ "string", "null" ]
+    }, {
+      "name" : "events",
+      "type" : {
+        "type" : "array",
+        "items" : "TimestampedEvent"
+      }
+    }, {
+      "name" : "complete",
+      "type" : "boolean"
+    } ]
+  } ],
+  "messages" : {
+    "getAllSpans" : {
+      "request" : [ ],
+      "response" : {
+        "type" : "array",
+        "items" : "Span"
+      }
+    }
+  }
+}
\ No newline at end of file