[erlang-questions] Inserting a "seam" in external calls
Wed Nov 19 11:01:27 CET 2008
I spent time last night studying external calls in beam. What I wanted
to investigate is how difficult it is to insert an optional layer of
indirection that allow me to divert external calls to a mock or fake
module (as the terminology is used in testing).
beam_emu.c has the apply and fixed_apply functions that do the MFA
lookup, as well as the parameterized module and error_handler issues.
export.c contains the code that manages the single global hashlist
containing all exported functions in the system
beam_load.c makes sure there are stubs for all exports needed by a
module as it is being loaded.
Are you with me what I'm investigating for? I want a "seam", another
layer of indirection really, that would allow my test suite to
override external calls made from a module. And I want it to be
isolated to just that test, so another test on the same module, a test
executing concurrently, would not be affected and would perform the
indented external calls.
The functions apply and fixed_apply in beam_emu.c have access to the
Process pointer and the MFAs, that would be one place to put logic
that checks if calls to M should be diverted, for which modules
calling into M, and for which processes (or having which group leader)
this should be done. Is this the only place external calls are made
Ideally, this indirection should add as little overhead as possible in
per process size and per external call performed. This could make it a
candidate for EEPing into OTP, otherwise I dont think many would want
I did see some code in beam_load.c that iterated through the import
table of the beam file it was loading, and it had an array of MFAs of
bifs that it allowed to be redefined, it contained erlang:apply/2 and
3. What does this mean? Can a module override erlang:apply for its own
nefarious goals and all external calls will change due to it?
More information about the erlang-questions