Archive for category erlang
Concurrency testing in Erlang with libtest
Posted by Hyperthunk in erlang, TDD, testing on August 10, 2010
I’ve just started a new project, with the aim of making it easier to test the concurrent programs I write in Erlang. My stated aims are quite simple:
- Provide services for capturing inter-process messages and context
- Provide support for stubbing out processes and OTP behaviours
- Provide hamcrest matchers that make it simple to define assertions about your application’s behaviour
It’s all in a very early stage (apart from my Erlang implementation of hamcrest, which is coming along nicely now) and the source code is available on github here. Here are a couple of samples to whet the appetite:
?assertThat(registered_name(Mod), observed_message_from(self(), Msg)),
?assertThat(registered_name(Slave, ProcessName), observed_message(Msg)),
?assertThat(Pid, observed_message({message, "hello"})),
?assertThat(?COLLECTOR,
categorises(observed_message({message, "woo hoo"}),
as(category1))).
Stubbing of OTP behaviours will almost certainly be based on emock, and I’m planning on integrating nicely with PropEr as I’ve started using this library quite a lot myself. The mechanics of replacing registered gen_servers and the like (using runtime code generation and/or re-registration/config), I’ll probably leave alone as there are plenty of good libraries out there that do this already.
Post compile hooks with rebar
Posted by Hyperthunk in builds, erlang, python on July 13, 2010
Sometimes you want your build to do some additional work after compiling. For example, in my Erlang implementation of hamcrest, I dynamically generate the main header file after compiling to ensure that all the functions exported from the hamcrest_matchers module are imported when the header gets included and to ensure that wrapper macros for eunit are also generated for each of them.
Typically you’d just have a makefile deal with this, maybe like so:
compile:
./rebar compile; escript header_gen
But that kind of breaks other people’s builds if they want to use rebar themselves. The problem is that rebar doesn’t yet provide a mechanism for overriding the build/compile command for dependencies (at all, let alone individually) and thus if your build requires a makefile to be run then your consumers build has to incur the same kind of complexity. Fortunately there is a work-around. Rebar provides a compile_post_script hook which you can specify in your rebar.config file. You specify a shell command and rebar will run this hook immediately after compilation. Unfortunately it also runs it when the compile command is applied to all your dependencies (again this is something which isn’t controllable yet) which typically will break because your shell command is not relevant to these apps. I spent a little time trying to do something clever with erl --eval '...' but in the end that didn’t play nicely at all. I then tried to encode the whole thing in a compound shell command like if [ -f hrlgen ]; then escript hrl; fi but then discovered that rebar_utils:sh/1 (which runs the shell command) wraps the supplied command text in an exec system call (which obviously isn’t going to work for a complex if..then expression). In the end, it was a comedic reptile that came to the rescue:
{compile_post_script,
"env ERL_LIBS=deps python -c \"import os; os.path.isfile('hrlgen') and os.system('escript hrlgen') or None\""}.
Using epm to overcome rebar dependency handling limitations
Posted by Hyperthunk in builds, erlang on July 1, 2010
I love rebar as a build tool, but occasionally it doesn’t do what I want. One example that keeps cropping up is managing dependencies that require complex commands in order to build them. If the dependency you want to manage is built using autotools or requires a series of commands (configure && make for example) then rebar is going to fail when you try and run ./rebar check-deps which is annoying. Read the rest of this entry »
urlconf for erlang
Posted by Hyperthunk in erlang, functional programming on April 2, 2009
O2 and I are at it again – this time with a mixture of python, xslt and erlang soup’n up to provide what will be the best and best value e-marketting tool around. The python part is that our shop window is written in django, with lots of jQuery magic providing a slick UI. I’m particularly fond of jQuery and my favoured style of web development is to implement the back-end as a RESTful web service and then consume and decorate this web exposure with a dynamic UI. The reason behind django (as opposed to one of the millions of other web frameworks) is that we both know python inside out. And I get plenty of ruby hacking done both at work (where we are near OCD about capistrano) and in developing much of axiom.
So where does the erlang part come in? Well that’s not all up for public consumption, but suffice to say there is a fair chunk of what we’re planning to do which is what I would call “infrastructure programming” and that is something that erlang is basically perfect for. Not least of what we need is a distributed, fault tolerant grid without spending much money either building or hosting the thing, and again, we’re on to the right tool for the job.
Some of what we’ll be doing involves handling http requests, and for that, I’m currently in favour of using either mochiweb or yaws. For our needs, the former is a simpler choice but one thing that mochiweb doesn’t provide out of the box is a way to map requests to the appropriate chunk of request handling code. Our latest open source forray aims to add this capability, albeit in a way that isn’t specifically tied to mochiweb.
Enter urlconf-erlang. There’s no link because the source code still lives in a private repo and we’re not ready to release it yet. 🙂
Inspired by someone’s laudible effort to implement the django templating language in erlang, we decided to implement something akin to django’s url mapping system for our own evil purposes. Our current implementation only really deals with a single layer of mappings and does so by simply matching the url against a regex and returning the MFA (Module, Function, Args) configured against it. A quick peek at one of the test cases should make this a bit clearer:
named_arguments_supported_by_regex_impl(_) ->
Path = "/users/fwnext-retail/billing-address",
Rx = "/users/(?.*)/(?.*)$",
Config = {
httpd.urlconf.regex,
[{Rx, my.controllers.users, {
my_user_function,
[uname, subcomponent]
}}]
},
server:start(Config),
expect_that(
server:lookup_dispatcher(Path),
matches(
{mfa, {
my.controllers.users,
my_user_function,
[
{uname, "fwnext-retail"},
{subcomponent, "billing-address"}
]
}})
).
As you can see there is some cruft because none of the Erlang regex libraries support named capture groups particularly well. In addition to this, we’re using the .re top level module (which is still not officially supported in R12B) as it is the only implementation we’ve found that is both fast and reliable. Because the choice of regex ibrary is likely to be a contentious point, we’ve taken the step of making the urlconf server a parameterized module, allowing you to pass in your own regex implementation instead of ours.
common_test code coverage failure
Posted by Hyperthunk in erlang, work on January 27, 2009
I’ve been trying to get common_test working with code coverage and one of the more esoteric (annoying!?) issues I’ve run into is that the cover tool doesn’t work properly with packages. There is a workaround, which I mention here, but that will only fix the problem with cover. In addition to this, the ct_cover module will produce reports without proper links to coverage info unless you copy the source code over the corresponding ebin directories. It would be *really* nice if this got sorted out.
Misunderstood…
Posted by Hyperthunk in erlang on February 12, 2008
functional programming and OO. I’ve decided to address some of these issues over the coming weeks, as much of this debate is raging in my workplace currently. But for now, I’d like to address a question raised some weeks ago by one of my co-workers.
Along with some fellow Erlangers, I was demonstrating Erlang and OTP to selected members of our 60 strong engineering group during a planning meeting in Dublin. One of the attendees asked a telling question: “what about when things change.” Reading between the lines, I could tell that my friend and colleague was really asking about the ease with which you can modify (and thereby maintain and potentially extend) Erlang code. His point of comparison was Java or, to be less specific, languages/platforms that support the Object Oriented paradigm.
The ways in which an object oriented language/platform facilitates change are many, but perhaps the best known of these is polymorphism. The ability to change behaviour at runtime by supplying an invocation target which shares a common, base interface, but overrides the target function with its own implementation: this “ability” is not unique to OO platforms at all. The mechanism used by languages such as C++, Java and .NET varies a little, but the terminology does not. In a langauge that uses manifest typing, such virtual resolution of an invocation target, relies on a mechnism known as dynamic binding (sometimes also called dynamic dispatch). Functional languages are not without support for changing their invocation targets at runtime, but in general, use a different
set of mechanics to do so. The strongly typed, non-strict, functional programming langauge Haskell, for example, has full support for polymorphic types and functions, but the mechanics of polymorphism are wildly different to those used by imperative languages.
Another set of langauges also support polymorphism, without the use of parameterized types and type constraints found in Haskell and minus the implementation and/or interface inheritance requirements of C++, Java and the .NET family of languages. These dynamically typed languages include Python,
Ruby, and Perl, to name but a few. Such langauges support the kind of ad-hoc polymorphism found in other imperative, Object Oriented langauges. It is both to this family of langauges, as well as the family of functional programming langauges, that Erlang belongs.
Erlang does support polymorphism, as do most other functional languages. Erlang is not strongly typed, it is dynamically typed; In this respect, Erlang is unlike the Algol familiy of langauges to which Java and C# belong. This difference is not as apparent as Erlang’s functional heritage, but can be just as conceptually tricky to understand if you have little or no background in dynamic languages.
The root of dispatch in dynamically typed langauges isn’t based on the ‘class’ of a reference, but rather on the target site’s responding to the message being passed; A concept sometimes called duck typing. Because Erlang’s type system is not rooted in the mechanics of classification and implementation inheritance, it is sometimes difficult to see that duck typing is there, just beneath the surface. Erlang’s lack of static typing means that this kind of late binding is ubiquitous. There are some esoteric examples such as message passing between processes (selective receive being a weak – and one sided – interface contract of sorts) and parameterised modules (which are good for building modules that act like functors). Besides these however, the simple case of stashing a module name in a variable will suffice to prove this point:
run(Thing, Mod) -> Mod:run(Thing).