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/23 08:57:38 UTC

svn commit: r988004 [3/3] - in /avro/trunk: ./ lang/java/src/java/org/apache/avro/ipc/stats/ lang/java/src/java/org/apache/avro/ipc/trace/ lang/java/src/java/org/apache/avro/ipc/trace/static/ lang/java/src/java/org/apache/avro/ipc/trace/templates/ lang...

Added: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/static/tipsy.js
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/static/tipsy.js?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/static/tipsy.js (added)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/static/tipsy.js Mon Aug 23 06:57:37 2010
@@ -0,0 +1,92 @@
+/*!
+ * The MIT License
+ * 
+ * Copyright (c) 2008 Jason Frame (jason@onehackoranother.com)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+pv.Behavior.tipsy = function(opts) {
+  var tip;
+
+  /**
+   * @private When the mouse leaves the root panel, trigger a mouseleave event
+   * on the tooltip span. This is necessary for dimensionless marks (e.g.,
+   * lines) when the mouse isn't actually over the span.
+   */
+  function trigger() {
+    $(tip).tipsy("hide");
+  }
+
+  /**
+   * @private When the mouse leaves the tooltip, remove the tooltip span. This
+   * event handler is declared outside of the event handler such that duplicate
+   * registrations are ignored.
+   */
+  function cleanup() {
+    if (tip) {
+      tip.parentNode.removeChild(tip);
+      tip = null;
+    }
+  }
+
+  return function(d) {
+      /* Compute the transform to offset the tooltip position. */
+      var t = pv.Transform.identity, p = this.parent;
+      do {
+        t = t.translate(p.left(), p.top()).times(p.transform());
+      } while (p = p.parent);
+
+      /* Create and cache the tooltip span to be used by tipsy. */
+      if (!tip) {
+        var c = this.root.canvas();
+        c.style.position = "relative";
+        $(c).mouseleave(trigger);
+
+        tip = c.appendChild(document.createElement("div"));
+        tip.style.position = "absolute";
+        $(tip).tipsy(opts);
+      }
+
+      /* Propagate the tooltip text. */
+      tip.title = this.title() || this.text();
+
+      /*
+       * Compute bounding box. TODO support area, lines, wedges, stroke. Also
+       * note that CSS positioning does not support subpixels, and the current
+       * rounding implementation can be off by one pixel.
+       */
+      if (this.properties.width) {
+        tip.style.width = Math.ceil(this.width() * t.k) + 1 + "px";
+        tip.style.height = Math.ceil(this.height() * t.k) + 1 + "px";
+      } else if (this.properties.radius) {
+        var r = this.radius();
+        t.x -= r;
+        t.y -= r;
+        tip.style.height = tip.style.width = Math.ceil(2 * r * t.k) + "px";
+      }
+      tip.style.left = Math.floor(this.left() * t.k + t.x) + "px";
+      tip.style.top = Math.floor(this.top() * t.k + t.y) + "px";
+
+      /*
+       * Cleanup the tooltip span on mouseout. Immediately trigger the tooltip;
+       * this is necessary for dimensionless marks.
+       */
+      $(tip).mouseleave(cleanup).tipsy("show");
+    };
+};

Added: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/collection.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/collection.vm?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/collection.vm (added)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/collection.vm Mon Aug 23 06:57:37 2010
@@ -0,0 +1,40 @@
+##
+## 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.
+
+## Display statistics for a collection of traces
+
+#parse( "org/apache/avro/ipc/trace/templates/common.vm" )
+
+<html>
+<head>
+<title>Avro Trace Results</title>
+#mediaIncludes()
+</head>
+<body>
+#if( $collection )
+  <h2> <a href="/overview/">Return to patterns</a> </h2>
+  <h1>Execution Pattern Overview</h1>
+  #printCollectionSummary( $collection )
+  <h1>High Latency Calls</h1>
+  #foreach ( $trace in $collection.longestTraces(10) )
+    #printTraceStats($trace)
+  #end
+#else
+  <h1>Collection not Found</h2>
+#end
+</body>
+</html>
\ No newline at end of file

Added: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm (added)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/common.vm Mon Aug 23 06:57:37 2010
@@ -0,0 +1,104 @@
+##
+## 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.
+
+## Common macros for avro trace
+
+#macro( printNode $collection_id $stats $depth )
+<tr>
+<td>
+#foreach ( $num in [0..$depth] )
+  &nbsp;
+#end
+<a href="/collection/$collection_id/$stats.hashCode()">$stats.MessageName</a>
+</td>
+<td><strong>$stats.getAverageTime($stats.getTraceTimings())</strong></td>
+<td>($stats.getMinTime($stats.getTraceTimings())</td>
+<td>- $stats.getMaxTime($stats.getTraceTimings()))</td>
+<td><strong>$stats.getAverageBytes($stats.getRequestPayloads())</strong></td>
+<td>($stats.getMinBytes($stats.getRequestPayloads())</td>
+<td>- $stats.getMaxBytes($stats.getRequestPayloads()))</td>
+<td><strong>$stats.getAverageBytes($stats.getResponsePayloads())</strong></td>
+<td>($stats.getMinBytes($stats.getResponsePayloads())</td>
+<td>- $stats.getMaxBytes($stats.getResponsePayloads()))</td>
+</tr>
+#set( $depth = $depth + 1 )
+#foreach ($child in $stats.Children)
+  #printNode( $collection_id $child $depth )
+#end
+#set( $depth = $depth - 1 )
+#end
+
+#macro ( printCollectionSummary $collection )
+<table>
+  <tr>
+    <td> Message </td>
+    <td colspan=3>Latency</td>
+    <td colspan=3>Request Payload</td>
+    <td colspan=3>Response payload</td>
+  </tr> 
+  #printNode($collection.getExecutionPathHash() $collection.getRootNode() 0)
+</table>
+<br><br>
+#end 
+
+#macro ( printTraceStats $trace )
+<table>
+  <tr>
+    <td> Message </td>
+    <td> Client </td>
+    <td> Server </td>
+    <td> Latency </td>
+    <td>Request payload</td>
+    <td>Response payload</td>
+  </tr> 
+  #printTraceNode($trace.getRoot() 0)
+</table>
+<br><br>
+#end 
+
+#macro( printTraceNode $traceNode $depth )
+<tr>
+<td>
+#foreach ( $num in [0..$depth] )
+  &nbsp;
+#end
+$traceNode.getMessageName()
+</td>
+<td>$traceNode.getRequestorHostname()</td>
+<td>$traceNode.getResponderHostname()</td>
+<td>$traceNode.getLatencyTimeString()</td>
+<td>$traceNode.getRequestPayloadSize()</td>
+<td>$traceNode.getRequestPayloadSize()</td>
+</tr>
+#set( $depth = $depth + 1 )
+#foreach ($child in $traceNode.Children)
+  #printTraceNode( $child $depth )
+#end
+#set( $depth = $depth - 1 )
+#end
+
+
+#macro ( mediaIncludes )
+<script type="text/javascript" src="static/protovis-r3.2.js"></script>
+<script type="text/javascript" src="static/tipsy.js"></script>
+<script src="static/jquery-1.4.2.min.js" type="text/javascript"></script>
+<script src="static/jquery.tipsy.js" type="text/javascript"></script>
+<script src="static/tipsy.js" type="text/javascript"></script>
+<link href="static/tipsy.css" type="text/css" rel="stylesheet"/>
+<script src="static/avro.js" type="text/javascript"></script>
+<link href="static/avro.css" type="text/css" rel="stylesheet"/>
+#end
\ No newline at end of file

Added: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm (added)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/node.vm Mon Aug 23 06:57:37 2010
@@ -0,0 +1,39 @@
+##
+## 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.
+
+## Display statistics for an individual node in the trace.
+#parse( "org/apache/avro/ipc/trace/templates/common.vm" )
+
+
+<html>
+<head>
+<title>Avro Trace Results</title>
+#mediaIncludes()
+</head>
+<body>
+#if( $collection )
+  <h2> <a href="/overview/">Return to patterns</a> </h2>
+  <h1>Execution Pattern Overview</h1>
+  
+  #printCollectionSummary( $collection )
+  #if( $node )
+    <h1>$node.getMessageName()</h1>	
+  #end
+  NOT IMPLEMENTED
+#end
+</body>
+</html>

Added: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm (added)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/overview.vm Mon Aug 23 06:57:37 2010
@@ -0,0 +1,45 @@
+##
+## 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.
+
+## Display the group of collections found after retrieving spans.
+
+#parse( "org/apache/avro/ipc/trace/templates/common.vm" )
+
+<html>
+<head>
+<title>Avro Trace Results</title>
+#mediaIncludes()
+</head>
+<body>
+<h1>Avro Trace Results</h1>
+<p>
+From $spans.size() spans found $collections.size() execution patterns.<br>
+</p>
+
+#set($count = 0)
+#foreach( $col in $collections )
+  <a href="/collection/$col.getExecutionPathHash()">Pattern $count</a>
+  #printCollectionSummary( $col )
+  #set($count = $count + 1) 
+#end
+
+<p>
+You can always <a href="/">collect more spans</a>. 
+</p>
+</table>
+</body>
+</html>
\ No newline at end of file

Added: avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm (added)
+++ avro/trunk/lang/java/src/java/org/apache/avro/ipc/trace/templates/traceinput.vm Mon Aug 23 06:57:37 2010
@@ -0,0 +1,35 @@
+##
+## 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.
+
+## Display an input form to retrieve span data.
+
+<html>
+<head><title>Avro Trace</title></head>
+<body>
+<h1>Welcome to Avro Trace!</h1>
+
+<form method='post'>
+<h3>Please enter the machines on which Avro's TracePlugin is running.</h3>
+<p>This input expects newline separated "host:port" pairs. By default, the
+TracePlugin serves tracing data on $default_port.</p>
+
+<textarea rows=10 cols=60 name='servers'>$last_input</textarea>
+
+
+<input type='submit' name='Start Tracing'>
+</form>
+</html>

Modified: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java?rev=988004&r1=988003&r2=988004&view=diff
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java (original)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestBasicTracing.java Mon Aug 23 06:57:37 2010
@@ -23,9 +23,7 @@ import static org.junit.Assert.assertTru
 
 import java.io.IOException;
 import java.net.URL;
-import java.nio.ByteBuffer;
 import java.util.List;
-import java.util.Random;
 
 import org.apache.avro.Protocol;
 import org.apache.avro.Protocol.Message;
@@ -39,7 +37,6 @@ import org.apache.avro.ipc.HttpTransceiv
 import org.apache.avro.ipc.RPCPlugin;
 import org.apache.avro.ipc.Responder;
 import org.junit.Test;
-import org.mortbay.log.Log;
 
 public class TestBasicTracing {
   Protocol protocol = Protocol.parse("" + "{\"protocol\": \"Minimal\", "
@@ -146,7 +143,7 @@ public class TestBasicTracing {
    *                       D: 21007
    */
   
-  Protocol advancedProtocol = Protocol.parse("{\"protocol\": \"Advanced\", "
+  static Protocol advancedProtocol = Protocol.parse("{\"protocol\": \"Advanced\", "
       + "\"messages\": { " 
       +  "\"w\": { \"request\": [{\"name\": \"req\", \"type\": \"int\"}], "
       + "   \"response\": \"int\"},"
@@ -203,6 +200,21 @@ public class TestBasicTracing {
     }
   }
   
+  /** Alternative Middle Responder */
+  static class NonRecursingResponder extends GenericResponder {
+    public NonRecursingResponder(Protocol local) 
+    throws Exception {
+      super(local);
+    }
+
+    @Override
+    public Object respond(Message message, Object request)
+        throws IOException {
+       assertTrue("w".equals(message.getName()));
+      return 6;
+    }
+  }
+  
   /** Endpoint responder */
   static class EndpointResponder extends GenericResponder {
     public EndpointResponder(Protocol local) {
@@ -358,42 +370,65 @@ public class TestBasicTracing {
    * @throws Exception
    */
   public static void main(String[] args) throws Exception {
-    if (args.length == 0) {
-      args = new String[] { "7002", "7003" };
-    }
-    Protocol protocol = Protocol.parse("{\"protocol\": \"sleepy\", "
-        + "\"messages\": { \"sleep\": {"
-        + "   \"request\": [{\"name\": \"millis\", \"type\": \"long\"}," +
-          "{\"name\": \"data\", \"type\": \"bytes\"}], "
-        + "   \"response\": \"null\"} } }");
-    Log.info("Using protocol: " + protocol.toString());
-    Responder r = new SleepyResponder(protocol);
-    TracePlugin p = new TracePlugin(new TracePluginConfiguration());
-    r.addRPCPlugin(p);
-
-    // Start Avro server
-    new HttpServer(r, Integer.parseInt(args[0]));
+    TracePluginConfiguration conf = new TracePluginConfiguration();
+    conf.traceProb = 1.0;
+    conf.port = 51010;
+    conf.clientPort = 12346;
+    TracePlugin aPlugin = new TracePlugin(conf);
+    conf.port = 51011;
+    conf.clientPort = 12347;
+    TracePlugin bPlugin = new TracePlugin(conf);
+    conf.port = 51012;
+    conf.clientPort = 12348;
+    TracePlugin cPlugin = new TracePlugin(conf);
+    conf.port = 51013;
+    conf.clientPort = 12349;
+    TracePlugin dPlugin = new TracePlugin(conf);
+    conf.port = 51014;
+    conf.clientPort = 12350;
+    TracePlugin ePlugin = new TracePlugin(conf);
+    conf.port = 51015;
+    conf.clientPort = 12351;
+    TracePlugin fPlugin = new TracePlugin(conf);
+    
+    // Responders
+    Responder bRes = new RecursingResponder(advancedProtocol, bPlugin);
+    bRes.addRPCPlugin(bPlugin);
+    HttpServer server1 = new HttpServer(bRes, 21005);
+    server1.start();
 
-    HttpTransceiver trans = new HttpTransceiver(
-        new URL("http://localhost:" + Integer.parseInt(args[0])));
-    GenericRequestor req = new GenericRequestor(protocol, trans); 
-    TracePluginConfiguration clientConf = new TracePluginConfiguration();
-    clientConf.clientPort = 12346;
-    clientConf.port = 12336;
-    clientConf.traceProb = 1.0;
-    req.addRPCPlugin(new TracePlugin(clientConf)); 
+    Responder cRes = new EndpointResponder(advancedProtocol);
+    cRes.addRPCPlugin(cPlugin);
+    HttpServer server2 = new HttpServer(cRes, 21006);
+    server2.start();
+    
+    Responder dRes = new EndpointResponder(advancedProtocol);
+    dRes.addRPCPlugin(dPlugin);
+    HttpServer server3 = new HttpServer(dRes, 21007);
+    server3.start();
+    
+    
+    // Root requestors
+    HttpTransceiver trans1 = new HttpTransceiver(
+        new URL("http://localhost:21005")); // recurse
+    HttpTransceiver trans2 = new HttpTransceiver(
+        new URL("http://localhost:21007")); // no recurse
+    
+    
+    GenericRequestor r1 = new GenericRequestor(advancedProtocol, trans1);
+    r1.addRPCPlugin(aPlugin);
+    
+    GenericRequestor r2 = new GenericRequestor(advancedProtocol, trans2);
+    r2.addRPCPlugin(fPlugin);
+    
+    GenericRecord params = new GenericData.Record(
+        advancedProtocol.getMessages().get("w").getRequest());
+    params.put("req", 1);
     
-    while(true) {
+    while (true){
+      r1.request("w", params);
+      r2.request("x", params);
       Thread.sleep(1000);
-      GenericRecord params = new GenericData.Record(protocol.getMessages().get(
-        "sleep").getRequest());
-      Random rand = new Random();
-      params.put("millis", Math.abs(rand.nextLong()) % 1000);
-      int payloadSize = Math.abs(rand.nextInt()) % 10000;
-      byte[] payload = new byte[payloadSize];
-      rand.nextBytes(payload);
-      params.put("data", ByteBuffer.wrap(payload));
-      req.request("sleep", params);
     }
   }
 }

Added: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestStaticServlet.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestStaticServlet.java?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestStaticServlet.java (added)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestStaticServlet.java Mon Aug 23 06:57:37 2010
@@ -0,0 +1,32 @@
+/**
+ * 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 static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class TestStaticServlet {
+  @Test
+  public void testEmptyQueryString() {
+    StaticServlet servlet = new StaticServlet();
+    assertNull(servlet.getResource("/"));
+    assertNull(servlet.getResource("bogusquery"));
+  }
+}

Added: avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTraceCollection.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTraceCollection.java?rev=988004&view=auto
==============================================================================
--- avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTraceCollection.java (added)
+++ avro/trunk/lang/java/src/test/java/org/apache/avro/ipc/trace/TestTraceCollection.java Mon Aug 23 06:57:37 2010
@@ -0,0 +1,98 @@
+package org.apache.avro.ipc.trace;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.avro.generic.GenericData;
+import org.apache.avro.generic.GenericRecord;
+import org.apache.avro.generic.GenericRequestor;
+import org.apache.avro.ipc.HttpServer;
+import org.apache.avro.ipc.HttpTransceiver;
+import org.apache.avro.ipc.Responder;
+import org.apache.avro.ipc.trace.SpanAggregator.SpanAggregationResults;
+import org.apache.avro.ipc.trace.TestBasicTracing.EndpointResponder;
+import org.apache.avro.ipc.trace.TestBasicTracing.RecursingResponder;
+import org.junit.Test;
+
+public class TestTraceCollection {
+  @Test
+  public void testRecursingTrace() throws Exception {
+    TracePluginConfiguration conf = new TracePluginConfiguration();
+    conf.traceProb = 1.0;
+    conf.port = 51010;
+    conf.clientPort = 12346;
+    TracePlugin aPlugin = new TracePlugin(conf);
+    conf.port = 51011;
+    conf.clientPort = 12347;
+    TracePlugin bPlugin = new TracePlugin(conf);
+    conf.port = 51012;
+    conf.clientPort = 12348;
+    TracePlugin cPlugin = new TracePlugin(conf);
+    conf.port = 51013;
+    conf.clientPort = 12349;
+    TracePlugin dPlugin = new TracePlugin(conf);
+    
+    // Responders
+    Responder bRes = new RecursingResponder(TestBasicTracing.advancedProtocol, bPlugin);
+    bRes.addRPCPlugin(bPlugin);
+    HttpServer server1 = new HttpServer(bRes, 21005);
+    server1.start();
+
+    Responder cRes = new EndpointResponder(TestBasicTracing.advancedProtocol);
+    cRes.addRPCPlugin(cPlugin);
+    HttpServer server2 = new HttpServer(cRes, 21006);
+    server2.start();
+    
+    Responder dRes = new EndpointResponder(TestBasicTracing.advancedProtocol);
+    dRes.addRPCPlugin(dPlugin);
+    HttpServer server3 = new HttpServer(dRes, 21007);
+    server3.start();
+    
+    // Root requestor
+    HttpTransceiver trans = new HttpTransceiver(
+        new URL("http://localhost:21005"));
+    
+    GenericRequestor r = new GenericRequestor(TestBasicTracing.advancedProtocol, trans);
+    r.addRPCPlugin(aPlugin);
+    
+    GenericRecord params = new GenericData.Record(
+        TestBasicTracing.advancedProtocol.getMessages().get("w").getRequest());
+    params.put("req", 1);
+    
+    for (int i = 0; i < 40; i++) {
+      r.request("w", params);  
+    }
+    
+    List<Span> allSpans = new ArrayList<Span>();
+    allSpans.addAll(aPlugin.storage.getAllSpans());
+    allSpans.addAll(bPlugin.storage.getAllSpans()); 
+    allSpans.addAll(cPlugin.storage.getAllSpans());
+    allSpans.addAll(dPlugin.storage.getAllSpans());
+
+    SpanAggregationResults results = SpanAggregator.getFullSpans(allSpans);
+    
+    assertEquals(0, results.incompleteSpans.size());
+    List<Span> merged = results.completeSpans;
+    List<Trace> traces = SpanAggregator.getTraces(merged).traces;
+    
+    assertEquals(40, traces.size());
+    TraceCollection collection = new TraceCollection(traces.get(0));
+    for (Trace t: traces) {
+      collection.addTrace(t);
+    }
+    server1.close();
+    server2.close();
+    server3.close();
+    aPlugin.httpServer.close();
+    aPlugin.clientFacingServer.stop();
+    bPlugin.httpServer.close();
+    bPlugin.clientFacingServer.stop();
+    cPlugin.httpServer.close();
+    cPlugin.clientFacingServer.stop();
+    dPlugin.httpServer.close();
+    dPlugin.clientFacingServer.stop();
+  }
+}

Modified: 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=988004&r1=988003&r2=988004&view=diff
==============================================================================
--- avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr (original)
+++ avro/trunk/share/schemas/org/apache/avro/ipc/trace/avroTrace.avpr Mon Aug 23 06:57:37 2010
@@ -79,4 +79,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file