[erlang-questions] Unidirectional architectures in Erlang

Jachym Holecek freza@REDACTED
Fri Aug 31 20:25:20 CEST 2018


# Rodrigo Stevaux 2018-08-30:
> If I may ask, I have a question about actor-based systems design that arose
> while writing a simple system for integrating GitHub and Slack.
> GitHub events are sent to a server using their Webhook API. We do some
> application logic on the events, and forward them to Slack.
> So our architecture is unidirectional: messages are followed from the HTTP
> server to a sequence of processes until they finally get to a message
> dispatcher process that sends messages to Slack.
> Message comes in, logic applies, message goes out.

Erlang comes by default with the brilliant Common Test application, I would
very much recommend giving it a try even if it may take a bit of effort to

> The generic servers are very easy to test in a pure fashion: just test the
> return values of handle_call for a given state.

Not really -- doing so violates abstraction boundaries and processes of such
variety typically do most of their useful work by performing side effects. So
either you have to introduce artificial complexity to satisfy requirements of
the test machinery (highly undesirable) or your test won't really capture
much (but you're still paying the maintenance cost for them).

> But:
> - unit testing should test that the unit under test forwards a message to a
> given address (and that is not reflected on the handle_call return value)
> - doing the integration testing of a "pipeline" of process involves testing
> that ultimately a message gets to the last process.

Good questions to be asking -- what assurances do you want to obtain from the
tests and consequently what granularity should you being testing at and what
methods and tools are available to assist. Also: what is the maintenance cost
of these tests looking forward, and does the utility of these justify them?

Black-box tests, whereby you start the whole thing, tickle its public
interfaces and see the right reactions come out the other end, tend to
always be desirable. You can do this against full cluster, individual
node, individual application, individual process, individual functions.

Common Test, with project-specific scaffolding around it, will be helpful
at all these levels. With it being ordinary Erlang code running as ordinary
Erlang node all the native communication and diagnostic facilities are also
available to you should you need to inspect or tweak something behind the
system's back. It is also not entirely out of the question for the production
code to be somewhat tweaked to cater for testing needs specifically, where
you can't get your way by more standard means.

Perhaps too broad an answer... my two cents anyways. :)

	-- Jachym

More information about the erlang-questions mailing list