In the author's words:
$ time sleep 12 real 0m12.003s $ time ./fluxcapacitor -- sleep 12 real 0m0.057s
It seems that this library might be useful to anyone needing to test communication protocols by helping tickle those edge cases that happen with timing.
Fluxcapacitor is really good at speeding up client/server or protocol tests. Actually fluxcapacitor was originally created to speed up the sockjs-protocol test suite. It wasn't possible to mock up a time library - we needed to run the tests against any sockjs http server, whether it's in erlang, node.js or python. It turns out the only way to run timeout-related tests in a reasonable time is to use fluxcapacitor. You might ask how fluxcapacitor works. In short - it uses ptrace to catch syscalls like clock_gettime or gettimeofday and overwrite the kernel response with a fake time. Additionally it short-circuits syscalls that can block for a timeout like select or poll. For technical details see the README.
Also - this is somewhat similar to golang race detector in spirit - looking for explicit synchronizations.
The general idea is that you should be able to run multiple processes within the thing, and that they should be able to just talk to each other freely.
There are a number of "protocol simulators" out there, but I always found them academic. I wanted to build a tool that will allow me run and test and do code coverage of my code, without having to wait forever for timeouts and timers to kick in to test rare branches.
For start, it seems like they hijack a bunch of clock calls with LD_PRELOAD and then redirect vdso ones to syscalls just so they can interpose with ptrace. Why not do the manipulation in the PRELOAD?
I guess using the debugger API makes it easier to coordinate a bunch of processes, but you could probably do the same thing with some sort of IPC mechanism between PRELOADED targets. In the common case (single program running under FC, no IPC is needed.
It's unclear to me why they force any sleep duration at all, e.g., 10ms: https://github.com/majek/fluxcapacitor/blob/master/src/main....
It seems like there is room to optimize here, if one were really inspired :-).
I would love to hear more about how this works, or get pointers to where one can learn about doing that kind of thing.
Edit: also worth mentioning that a good way of doing this kind of testing when you have full control of the code is by abstracting access to time operations to go through an interface and injecting mock/fake time objects.
But you don't always have access to the code, so I think this tool is very useful.
In Linux, ptrace is not re-entrant. This means you can't use fluxcapacitor on itself, or any other program that uses ptrace, e.g. a debugger.
Can anyone explain what happened here?
Here's a patch to get you started: https://gist.github.com/anonymous/bab9c0fcafd9a03acfaa89741f...
I don't know whether it even makes sense to try porting this to macOS, but good luck.