How to get your Orbited bugs fixed

The main thing to remember about bug reports is that we can't fix what we can't reproduce. That means that your job as the bug reporter is to give us something we can work with. Here's how.

Orbited's javascript is complicated and delicate. Sometimes bugs are caused by seemingly isolated changes to Orbited.js. If you find that one of your target browsers is affected by a bug, you must create a test-case to reproduce the problem. Without a test-case, Orbited developers will, in all likelihood, not pursue a fix for the bug. This document describes exactly how to submit your bug so as to get it fixed in a matter of hours or days, as opposed to weeks or never. If you send a half-formed bug report to the mailing list, you will more than likely be referred to this document. We simply don't have the resources to spend hours reproducing bugs. If you run into problems during the process of building a test-case, don't worry! It's okay to ask questions on the mailing list and IRC channel about building a test case.

Process

  1. Find a bug. Make sure that this bug isn't already in an outstanding ticket.
  2. Isolate the bug. Find the specific case where the bug manifests, as well as specific browsers/versions.
  3. Create the smallest possible example that still produces the bug.
  4. Put the entire sample in a single html file, and give it a descriptive name, such as "xdomain_refresh_reconnect.html". Do not use console.log; instead use Orbited.getLogger("test_name_here").log. Also create an Orbited.cfg file that will serve the test case file.
  5. Insert all details about the bug in the html file. Include a description, version of Orbited, and list of affected browsers. Even if you think your example speaks for itself, someone will misunderstand what you think the bug is, so include a specific description of which part of the output/result you consider to be a bug.
  6. Open a ticket on the Orbited.org tracker, and include the full text of the comment from your test case html file.
  7. Send an email to the list mentioning your bug, and include a link to the bug on the tracker.

Approach

Building a test-case in Orbited means isolating the problem to the extent that Orbited's built-in test servers can be used to replicate the bug. For instance, there have been numerous bugs associated with navigation and reloading in IE. These bugs aren't about complex web-application logic, or even a particularly special socket-server behind Orbited. They can be reproduced with an echo server, which ships with Orbited. The test case for such a bug, like any test case, consists of two parts: testcase.html (this will actually have a more descriptive name), which creates a connection to the echo server (via Orbited), then reloads the page and tries to create a new connection; and "orbited.cfg", which serves testcase.html and enables the echo server.

Sometimes the bug might be specific to cross-domain issues. These can almost always be reproduced as cross-port issues, and can be replicated by having Orbited listen on two ports. You can then access the testcase.html via "http://localhost:5000/testcase.html", and include Orbited.js via "http://localhost:8000/static/Orbited.js". This setup is identical to running a web-app on port 5000 and Orbited on port 8000.

Your specific application may seem too complicated and multi-faceted to reduce to an html and cfg file, but it's not. It's just a matter of isolating the bug, and choosing the appropriate built-in test server.

Tools

A number of tools will help building test cases. Here is an example orbited.cfg with all tools enabled (and a description of each):

# These modules can be accessed in the browser via the Orbited.test package.
[test]
# The stompdispatcher module provides an HTTP based api for dispatching stomp
# messages. In the browser:
# Orbited.test.stompdispatcher.send(destination, message);
stompdispatcher.enabled = 1

# Additionally, the socketcontrol module allows any open TCPSocket orbited session to be
# terminated. In the browser:
# t = Orbited.TCPSocket(); t.open(...); ... Orbited.test.socketcontrol.kill(t);

# Orbited ships with various basic servers for testing your applications.
# Note: be sure to add access rules for each of these in the [access] section
[listen]
# The embedded stomp server is morbidq (www.morbidq.com)
stomp://:61613

# The echo server accepts all connections and sends all data back, character by
# character.
echo://:9999

# The line echo server is like the echo server, but buffers data until a \n is
# received, then sends back all buffered data, including the \n
lineecho://:9998

# The rude server accepts connections, then immediately closes them
rude://:9997

# The announce server accepts all connection, and sends a json packet out every
# 3 seconds.
announce://:9996

Example: ActiveMQ + Orbited + Pylons

Here's the setup: Pylons serves an index page on port 5000, which includes Orbited.js from the running Orbited instance on port 8000. The index page also includes stomp.js to connect (via Orbited) to ActiveMQ running on port 61613 (or any stomp server, such as RabbitMQ or the built in morbidq server.)

There is a bug though: When you send a message to the /topic/hello, it is sent twice. Your challenge is to condense this into a single html file and an Orbited.cfg file test-case, server-side components and all.

Though your pylons app has a custom webserver running on port 5000, this test case does not. Instead, configure orbited to serve your testcase.html file on port 5000 with the following lines in config:

[listen]
http://:5000

[static]
testcase.html=testcase.html

We need Orbited to also listen on port 8000 in this test setup, so add http://:8000 to the listen section.

We also need to include the access rule for stomp:

[access]
http://:61613

Now we need a stomp server to take the place of rabbitmq, so we can use the built-in morbid server. Add stomp://:61613 to the listen section. Note: There are some cases where the bug really can't be reproduced without external servers, such as a rabbitmq specific bug that doesn't also manifest with morbid. These bugs seem to be rare though, so in general this approach should work.

We are missing only one final piece: a way to send a message to the stomp server. We could, of course, just send the message from the stomp.js client to the server, but it might be that the bug interferes with our browser stomp connection. Therefore, we use the built-in test stomp dispatcher. The stomp dispatcher is an HTTP api to send stomp messages without maintaining a full connection to the browser. It's cross-site (via dynamic script tag includes) and offers a straightforward api:

Orbited.test.stompdispatcher.send(channel_name, message);

And enable the stomp dispatcher in your orbited.cfg:

[test]
stompdispatcher.enabled = 1

Finally, we can create the actual test logic:

<script>
var logger = Orbited.getLogger('testcase');
onload = function() {
    stomp = new STOMPClient();
    stomp.connect('localhost', 61613);
    logger.log('connecting');
    stomp.onconnect = function() {
        logger.log('connected');
        stomp.subscribe('/topic/hello');
        logger.log('/subscribed to /topic/hello');
        // Send a stomp message to this channel in one second
        setTimeout(function() {
            logger.log('sending frame via Orbited stompdispatcher');
            Orbited.test.stompdispatcher.send('/topic/hello', {}, 'hello world');
        }, 1);
    }
    var counter = 0;
    stomp.onreadframe = function(frame) {
        counter++;
        logger.log('received frame: ' + frame)
        if (counter == 2) {
            logger.log('ERROR, received 2 frames for one publish');
        }
    }
}
</script>

Now we need to also describe the error in the html file:

<html>
<head>
  ... SCRIPTS ...
</head>
<body>
 <h1>Cross-subdomain stomp double onreadframe error</h1>
 <div>
  <h2>Affected Browsers</h2>
  <ul>
   <li>IE 6/7</li>
   <li>Firefox 2+</li>
   <li>Opera 8+</li>
   <li>Safari 2</li>
  </ul>
 </div>
 <div>
  <h2>Description</h2>
  When you subscribe to a channel, the very first message is sent twice, in all browsers but Safari 3 and the latest webkit.
 </div>
 <div>
  <h2>Testing</h2>
  The test will run on load. Look for the log message "ERROR, received 2 frames for one publish". This indicates that stomp.onreadframe was called twice, even though only one publish occured.  
</body>
</html>

TADA! Submit your bug report like this, and you can expect your problem to be dealt with in a timely fashion, because the Orbited team will actually have something to work with.