I hope you never need this. But if you do, you can get it from me on github here.
It’s a little craptacular at the moment, but it works. I will maintain and enhance it depending on demand.
I hope you never need this. But if you do, you can get it from me on github here.
It’s a little craptacular at the moment, but it works. I will maintain and enhance it depending on demand.
I decided I needed an hour break from Scala hacking, and I am about halfway finished with Sean Carroll's From Eternity to Here, which goes on at great length about entropy as it relates to time's arrow. So for the fun of it I whipped up a simulation of an Ehrenfest Urn using Processing.js.
Check it out here (requires a browser supporting canvas).
Now that I'm done, there are a couple of things I find amazing about this.
From eternity to here apparently involves a massive improvement in the state of the programming art. Everything is amazing and nobody's happy.
I've released a package that I've been using for well over a year now for the purpose of writing functional test suites against applications using Postgres. The executive summary is that PGProxy allows you to write tests that are transactionally isolated from one another, without doing anything special in your application code.
This project is aimed more at functional tests of a website (using something like Selenium) than it is for unit tests of a single class or module. In those cases, using mock objects or other strategies is more viable. But, you could certainly use PGProxy in those scenarios as well.
You can get it on github here: http://github.com/mcfunley/pgproxy.
PGProxy is written in Python using Twisted, and has its own extensive set of unit and functional tests.
If you have a sufficiently large set of functional tests written by a sufficiently large team, eventually naively-written tests will begin to interfere with one another. A really simple example of two tests that would interfere with one another would be:
Clearly, if we don't take any special precautions in our test suite, Test A will never succeed if it is run after Test B. And if we require that Test A always runs before Test B, then we're forced to recreate our fixture database in between test runs. And this is just two tests–when you're talking about thousands, the potential interactions can be huge. Not to mention that depending on big your fixture databases are, creation at the start of every run can be a pain.
So eventually you will probably decide it would be better to restore the fixture data to a known state in between test cases. There are a few different ways to try to accomplish this:
There are problems with all of these approaches. 1) is very slow. 2) is very tedious for developers and error prone. 3) is similarly tedious and can be slow, depending on how much logic creating your entities entails. 4) is really just moving the goalposts, because tests are still going to interfere with each other. 5) works to the extent that you can have all of your database access code share a connection and to the extent that your code does not try to use its own transactions.
But! I am writing this to tell you about an exciting new option, namely, "do something crazy." PGProxy is that crazy thing, and it works pretty well.
As mentioned above, your test case can only work inside of a transaction if you are able to use a single connection per database per test case. If your test case is making calls to multiple processes that all want to use your fixture database, that is a pretty difficult thing to do.
PGProxy solves the problem by, you guessed, it, proxying all of your database connections. So if you have a PHP site running in Apache and a scala service running in Jetty, they can now share database connections in your tests. And consequently, they can share a transaction.

The other issue that comes up in using transactions to make test cases is that it's pretty common for the code that you're testing to want to use its own transactions. PGProxy solves this by rewriting transaction usage within the test case into SAVEPOINT usage. In other words, if you have a test that runs this SQL:
BEGIN; update users set username='chuck' where username='steve'; COMMIT; BEGIN; update users set password='foo' where username='chuck'; ROLLBACK;
PGProxy will rewrite that to this:
BEGIN; -- my test case SAVEPOINT x; update users set username='chuck' where username='steve'; RELEASE SAVEPOINT x; SAVEPOINT y; update users set password='foo' where username='chuck'; ROLLBACK TO SAVEPOINT y; ROLLBACK; -- my test case
There are a few ways to run the proxy. If you are writing your test suite using python (ie, using unittest), you can set up your test runner like this:
from __future__ import with_statement
import pgproxy
this_dir = os.path.realpath(os.path.dirname(__file__))
pidfile = os.path.join(this_dir, 'pgproxy.pid')
logfile = os.path.join(this_dir, 'pgproxy.log')
def run():
# this will shut down the proxy when the tests complete.
with pgproxy.run(pidfile=pidfile, logfile=logfile):
run_test_suite()
def run_test_suite():
# this should actually run your tests
pass
if __name__ == '__main__':
run()
Or you can use something like this script to start a standalone pgproxy process:
#! /usr/bin/env python
import pgproxy
import os
this_dir = os.path.realpath(os.path.dirname(__file__))
pidfile = os.path.join(this_dir, 'pgproxy.pid')
logfile = os.path.join(this_dir, 'pgproxy.log')
pgproxy.run(listenPort=5433, serverAddr=('localhost', 5432),
pidfile=pidfile, logfile=logfile)
In both of these cases, PGProxy is configured to accept connections on port 5433, and to connect to the Postgres server running on port 5432. In these examples you would tell your application to connect to port 5433.
In order to run PGProxy, you need Twisted version 8.1.0 or later.
PGProxy accepts two special queries that signal the start and the end of tests. Your test suite will need to invoke these in setUp and tearDown (or whatever the equivalents are in the language / framework that you're using). Here's a unittest example:
class TestCase(unittest.TestCase):
def setUp(self):
self.query("BEGIN TEST '%s'" % self._testMethodName)
def tearDown(self):
self.query("ROLLBACK TEST '%s'" % self._testMethodName)
def test_something(self):
# now this has a transaction and can't do any serious damage
# to the fixture data.
pass
As you may have noticed above, the BEGIN/ROLLBACKS are sent to postgres with comments stating which test is running, which can be pretty handy if you find yourself needing to look at the postgres logs to debug something. Here you would see:
BEGIN; -- test_something ROLLBACK; -- test_something
Since setUp and tearDown are frequently overridden by developers for other purposes, I generally like to use a metaclass to wrap test cases in transactions instead. This way if a developer forgets to call the base test case's setUp method, it's no big deal for the rest of the suite. I'll leave that as an exercise. You get the idea.
Lord knows I have a complicated opinion of all things Twisted, and maybe someday I will write something about that. And by "someday" I mean I am almost certainly never going to, because I have enough trouble staying out of nerd fights on the internet.
But I have to say that for this project, with the precise set of requirements that it had, and taking as a given my pre-existing wealth of experience with Twisted, things worked out great. This was a from-scratch rewrite of my first version, which was written using asyncore. The asyncore version was riddled with obscure race conditions, and it turned out to be much easier to just rewrite the damned thing using an event-driven framework than it ever was to debug the original. There was not a better choice of Python framework for this project, though I did toy with the idea of using scala. Anyway, I hope this praise for Twisted doesn't come across as excessively faint.
Enjoy! Don't hesitate to drop me a line if you find this useful or have bug reports.
So, I have finally fixed this stupid site. I spent years devising plans for rewriting it in lisp, or something, then one day read this essay about perfectionism and decided I was being completely ridiculous. Yes, that is my dog in the header, thank you for asking.
Some would have balked at the prospect of hand editing years of predominantly embarrassing posts, but I soldiered on through good times and bad. I am still messing with the layout and I haven’t even looked at the damn thing in Internet Explorer yet. (If you have IE—I don’t at home—let me know if something is really messed up.)
Evidently, once upon a time I had a career writing a lot of code for various Microsoft platforms. I feel like that part of my life needs to remain there for posterity, even though I am very happily participating in the open source, OMG-scale web world these days.
If I leave those posts there, perhaps someday someone can explain them to me. Very few of them make any sense to me now. I do remember fielding the e-mail from the ignoramus I-banker that prompted me to write Significant Digits for the Inummerate. With a little luck, his life is now ruined forever.
I thought I would miss debugging obscure threading issues, and rooting through core dumps, and staring at disassembly, but I was wrong. I have come to appreciate the sublime beauty of fork, the challenge of writing code for epic scale, having the damn source code, and solving problems that matter to people that are not evil mutants. I haven’t hand-edited XML in two years. Life is beautiful. Hopefully with the whole “blog” issue out of the way I will be able to think of something interesting to talk about.
Well, if you use emacs long enough, eventually you realize that you have tens of thousands of lines of elisp lying around. I'm making a modest effort to dig myself out of this mess and what useful tidbits there are I will share with the world. Here is a very basic module that helps you get yourself in a predicament similar to my own.
;;;
;; elisp-ext.el
;;
;; Utilities for writing and debugging Emacs lisp. The
;; interactive functions are:
;;
;; elisp:goto-definition - Jumps to the source for a
;; defun, defvar, etc.
;;
;; elisp:edebug-at-point - Enable edebug for the symbol
;; nearest the cursor.
;;
;; When this is loaded, the sequence C-c C-g is bound to
;; elisp:goto-definition and C-c C-d is bound to
;; elisp:edebug-at-point in ielm and elisp-mode.
;;
;; by Dan McKinley, 2008
;; http://mcfunley.com
;;
;; This program is free software: you can redistribute it
;; and/or modify it under the terms of the GNU General Public
;; License as published by the Free Software Foundation, either
;; version 3 of the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
(eval-when-compile (require 'cl))
(defun* elisp:read-symbol (default &optional
(prompt "Symbol")
(test 'intern-soft))
(let (val)
(setq val (completing-read
(if default (format "%s (default %s): " prompt default)
(concat prompt ": "))
obarray test t nil nil
(and default (symbol-name default))))
(if (equal val "")
sym
(intern val))))
(defun elisp:goto-definition (sym)
"Extends find-func.el to find any symbol (defaulting
to the one at point)."
(interactive (list (elisp:read-symbol (symbol-at-point))))
(cond ((fboundp sym) (find-function sym))
((facep sym) (find-face-definition sym))
(t (find-variable sym))))
(defun elisp:edebug-function (fun)
"Enables edebug on a function given its symbol.
This necessarily leaves the file containing `fun' open, since
edebug will not open files on its own."
(when (subrp fun)
(error "Can't edebug a C function, sorry."))
(save-excursion
(let ((library (symbol-file fun nil)))
(destructuring-bind (buf . pos)
(find-function-search-for-symbol fun nil library)
(set-buffer buf)
(goto-char pos)
(forward-sexp)
(edebug-eval-top-level-form))))
fun)
(defun elisp:edebug-at-point (fun)
"Enables edebug on a function, defaulting to the
`function-called-at-point'."
(interactive
(list
(elisp:read-symbol
(function-called-at-point) "Debug function" 'fboundp)))
(message "Enabled debugging on %s." (elisp:edebug-function fun)))
(defun elisp:local-keys ()
(local-set-key "\C-c\C-g" 'elisp:goto-definition)
(local-set-key "\C-c\C-d" 'elisp:edebug-at-point))
(add-hook 'emacs-lisp-mode-hook 'elisp:local-keys)
(add-hook 'ielm-mode-hook 'elisp:local-keys)
(provide 'elisp-ext)
As a WPF user, I spend at least as much time reading and writing XAML as I do reading/writing C# code that does WPF-isms. I do spend a lot of time in C#, but little of it is WPF specific, which arguably is one of the strengths of WPF’s data/content facilities.
In my opinion, the sooner folks get thrown into the XAML pool the sooner they learn to swim.
(Emphasis mine.)
I thought the whole point of selling our souls to the XML devils was that development tools would deal with that slop for us.
Forget swimming. I am having trouble seeing any non-masochistic reason for me to learn this at all. I am just not getting through the Microsoft marketing on this one. I say this as somebody with deep-to-extremely-deep knowledge of most of the Microsoft tools of the last 10 years–I'm not Don Box, but I'm also no slouch.
Give me one good reason why I should spend my spare time learning an API that looks like this. (And it would be my spare time. I am still living here in the real world, where it still seems to be occasionally more practical to write Windows platform code in C++, for god's sake.)
Wikipedia reassures me–in a rather hilarious, pleonastic way–that this is "simply XML."
[A] key aspect of the technology is the reduced complexity needed for tools to process XAML, because it is simply XML. As a result, a variety of products are emerging, particularly in the WPF space, which create XAML-based applications. As XAML is simply based on XML, developers and designers are able to share and edit content freely amongst themselves without requiring compilation.
(Emphasis mine.)
Show me one XML-based API that does not, in one way or another, prove this to be an oxymoron. (See also: "Java programmer writes application which reads 243 XML files on startup then wonders why it takes 30 seconds to start." Thanks, Slava.)
Sometimes trite observations become trite because they are obviously correct. Who created the creator? Why re-invent the s-expressions that have been around since the 50's, but poorly? Et cetera. In these cases the fact that the criticism is well-worn does nothing to detract from it.
Maybe I am just being a grizzled old fogey (at the incredibly advanced age of 27.) It wouldn't be the first time that I have been described as a crotchety septugenarian in the body of a young adult. If I am way off the mark here, please enlighten me.
Update, May 20th: Jon Harrop avoids my bitching and gives solutions. See XAML or F#.
I suppose I finally had enough of the carpal tunnel caused by typing '\' to delimit directories (yes, powershell helps a little, but not enough).
Or, I decided I knew enough about Windows for now and needed to branch out.
Or maybe I was just in a rut.
Well, I'm happy about whatever it was that caused me to make my latest impulse purchase.

I've had it less than a week. Great stuff so far:
I guess that's mostly developer stuff, which is odd since Apple's marketing actively makes fun of programmers.
I don't see myself ceasing Windows development anytime in the next decade, though, so if you're only here for .NET debugging stuff I wouldn't head for the hills just yet.
I hate you guys. Seriously, drop dead.
SERVICE_NAME: ati hotkey poller
TYPE : 110 WIN32_OWN_PROCESS
(interactive)
STATE : 4 RUNNING
(NOT_STOPPABLE,
NOT_PAUSABLE,
ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
PID : 1132
FLAGS :
I wrote a small program that generates xml from a type library. The type library can be a .tlb, or embedded as a resource in a PE (.dll, .ocx, .exe, etc).
I'm using this as a build tool–basically it's the glue that makes a big project using C#, C++, VB6, WiX and NAnt hold together.
The source can be downloaded from this link. This doesn't grab everything from the tlb, but it's pretty simple and not hard to extend.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Copyright (c) 2005, Dan McKinley
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
- The name of Dan McKinley may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
using System;
using System.Collections.Generic;
using System.Text;
using isvc = System.Runtime.InteropServices;
using System.IO;
using System.Xml;
using System.Runtime.InteropServices.ComTypes;
namespace tlbspit
{
class Program
{
[isvc.DllImport("oleaut32.dll", PreserveSig = false)]
static extern void LoadTypeLib(
[isvc.MarshalAs(isvc.UnmanagedType.LPWStr)] string szFile,
[isvc.MarshalAs(isvc.UnmanagedType.Interface)] ref ITypeLib pLib);
static int Main(string[] args)
{
if (args.Length == 0)
{
Usage();
return -1;
}
try
{
string path = string.Join(" ", args);
using (XmlTextWriter w = new XmlTextWriter(Console.Out))
{
w.Formatting = Formatting.Indented;
Run(path, w);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return -1;
}
return 0;
}
static void Run(string path, XmlWriter w)
{
w.WriteStartElement("library");
ITypeLib tlb = null;
LoadTypeLib(path, ref tlb);
WriteTlbAttribs(tlb, w);
int ct = tlb.GetTypeInfoCount();
for (int i = 0; i < ct; i++)
{
ITypeInfo t = null;
tlb.GetTypeInfo(i, out t);
WriteType(t, w);
}
w.WriteEndElement();
}
static void WriteType(ITypeInfo t, XmlWriter w)
{
w.WriteStartElement("type");
ITypeInfo2 t2 = (ITypeInfo2)t;
TYPEKIND k;
t2.GetTypeKind(out k);
w.WriteAttributeString("name", NameOf(t));
w.WriteElementString("guid", GuidOf(t));
w.WriteElementString("kind", k.ToString());
w.WriteEndElement(); // type
}
static unsafe string GuidOf(ITypeInfo t)
{
IntPtr pAttr = IntPtr.Zero;
try
{
t.GetTypeAttr(out pAttr);
TYPEATTR* attr = (TYPEATTR*)pAttr;
Guid g = attr->guid;
return g.ToString();
}
finally
{
if (pAttr != IntPtr.Zero)
t.ReleaseTypeAttr(pAttr);
}
}
static string NameOf(ITypeInfo t)
{
string name = null, doc = null, hlpfile = null;
int i = 0;
t.GetDocumentation(-1, out name, out doc, out i, out hlpfile);
return name;
}
static string NameOf(ITypeLib tlb)
{
string name = null, doc = null, hlp = null;
int hc = 0;
tlb.GetDocumentation(-1, out name, out doc, out hc, out hlp);
return name;
}
static unsafe void WriteTlbAttribs(ITypeLib tlb, XmlWriter w)
{
IntPtr pAttr = IntPtr.Zero;
tlb.GetLibAttr(out pAttr);
try
{
TYPELIBATTR* attr = (TYPELIBATTR*)pAttr;
w.WriteAttributeString("guid", attr->guid.ToString());
w.WriteAttributeString("version",
string.Format("{0}.{1}", attr->wMajorVerNum, attr->wMinorVerNum));
w.WriteAttributeString("name", NameOf(tlb));
}
finally
{
if (pAttr != IntPtr.Zero)
tlb.ReleaseTLibAttr(pAttr);
}
}
static void Usage()
{
Console.WriteLine(@"
TLBSPIT by Dan McKinley
Writes out (some) of the attributes of a type library as xml to
standard output.
Usage: tlbspit.exe <type library file>
The file can be a dll/ocx/etc. or a tlb. It can optionally include a
slash followed by the number of a resource.
Examples:
tlbspit foo.tlb
tlbspit bar.dll\3
");
}
}
}
When I'm writing a GUI or a multithreaded server application, I make heavy use of OutputDebugString (and various API's that map to it). This is a very useful tool when the act of stepping through an application has side effects that drastically change the experiment. Unfortunately, it looks everyone else likes this API, too.
I try to be courteous and pay my developer taxes here–when my application is deployed to customers, rest assured that it will not be writing debugger output by default. I put my calls to OutputDebugString on a switch in one way or another, or I just compile them out in release mode.
(This is not just being kind to anyone trying to debug something else on a machine running my application. I need to do this to avoid embarrassment. I curse quite a bit in my traces.)
Not everybody is taking the trouble to do this. To wit:

If I open up dbmon or debugview and wave my mouse around a little, i'm inundated with messages from these applications:
I find it particularly annoying that my development tools are hampering my development in this way.