How to test methods with system calls

876 views
Skip to first unread message

mogwaing

unread,
Oct 22, 2008, 8:27:09 AM10/22/08
to Google C++ Testing Framework
I'm testing programs having some methods with system calls in them,
which are like write(2) or read(2).
Is there any way I can simulate those call errors with google test ?
If it can't be done, ss there any way to simulate those system call
errors without
modification in source codes ?

Hi, I'm not sure I can ask this question here, but
I'm very appreciated if someone respond to it.

Zhanyong Wan (λx.x x)

unread,
Oct 22, 2008, 3:09:25 PM10/22/08
to mogwaing, Google C++ Testing Framework
Hi,

On Wed, Oct 22, 2008 at 5:27 AM, mogwaing <mogw...@gmail.com> wrote:
>
>
> I'm testing programs having some methods with system calls in them,
> which are like write(2) or read(2).
> Is there any way I can simulate those call errors with google test ?
> If it can't be done, ss there any way to simulate those system call
> errors without
> modification in source codes ?

I'm afraid you need to modify your source code to make this testable,
but it can be a good thing as in the process you can make your code's
dependencies more clear.

The standard technique for dealing with this is called "mock objects"
and "dependency injection". There are many good articles on the web
about them - try to search and read some of them.

> Hi, I'm not sure I can ask this question here, but
> I'm very appreciated if someone respond to it.
>

--
Zhanyong

Bruce Trask

unread,
Oct 22, 2008, 5:57:35 PM10/22/08
to mogwaing, Google C++ Testing Framework
Ideally you would refactor the code to remove dependencies on these calls but if you can't then you can use either "link seams" or "preprocessor seams" to either link to a different library with the same symbols and functions in it or #define the name of the function to something else that you can control.
 
These types of seams are discussed in the books
"Working Effectively with Legacy Code.
 
Regards,
Bruce

mogwaing <mogw...@gmail.com> wrote:

Chandler Carruth

unread,
Oct 22, 2008, 6:11:44 PM10/22/08
to Bruce Trask, mogwaing, Google C++ Testing Framework
My favorite tactic is to combine a linked in interceptor for these
low-level functions with a nice robust mocking framework to allow you
to dynamically replace and simulate specific responses from the system
calls you care about. ;] It's useful for testing *after* you've
refactored your system calls into nice isolated pieces, which you just
want to verify. It's especially useful when the system calls are
completely impossible *to* verify due to their nature (chown, chroot,
etc).

I may look at contributing just such a tool to the eventual open
source mocking framework.

-Chandler

mogwaing

unread,
Oct 22, 2008, 9:03:04 PM10/22/08
to Google C++ Testing Framework
Hi Zhanyong
thank you for the keywords. I really appreciate it.

thanks,
Hiroyuki


On Oct 23, 4:09 am, "Zhanyong Wan (λx.x x)" <w...@google.com> wrote:
> Hi,
>

mogwaing

unread,
Oct 22, 2008, 9:08:08 PM10/22/08
to Google C++ Testing Framework
Hi Chandler,

Thanks for the reply. You mean like the following ?
I made the exactly the same function as write(2) and
created shared object for the function.
Then, it works with LD_PRELOAD like below.

LD_RELOAD=./mywrite.so ./test

my "test" program uses write in mywirte.so instead of write(2).
Thank you.

Hiroyuki


On Oct 23, 7:11 am, "Chandler Carruth" <chandl...@gmail.com> wrote:
> My favorite tactic is to combine a linked in interceptor for these
> low-level functions with a nice robust mocking framework to allow you
> to dynamically replace and simulate specific responses from the system
> calls you care about. ;] It's useful for testing *after* you've
> refactored your system calls into nice isolated pieces, which you just
> want to verify. It's especially useful when the system calls are
> completely impossible *to* verify due to their nature (chown, chroot,
> etc).
>
> I may look at contributing just such a tool to the eventual open
> source mocking framework.
>
> -Chandler
>
> On Wed, Oct 22, 2008 at 2:57 PM, Bruce Trask <bruce.tr...@mdesystems.com> wrote:
> > Ideally you would refactor the code to remove dependencies on these calls
> > but if you can't then you can use either "link seams" or "preprocessor
> > seams" to either link to a different library with the same symbols and
> > functions in it or #define the name of the function to something else that
> > you can control.
>
> > These types of seams are discussed in the books
> > "Working Effectively with Legacy Code.
>
> > Regards,
> > Bruce
>

Chandler Carruth

unread,
Oct 22, 2008, 9:36:55 PM10/22/08
to mogwaing, Google C++ Testing Framework
On Wed, Oct 22, 2008 at 6:08 PM, mogwaing <mogw...@gmail.com> wrote:
>
> Hi Chandler,
>
> Thanks for the reply. You mean like the following ?
> I made the exactly the same function as write(2) and
> created shared object for the function.
> Then, it works with LD_PRELOAD like below.
>
> LD_RELOAD=./mywrite.so ./test
>
> my "test" program uses write in mywirte.so instead of write(2).
> Thank you.
>
> Hiroyuki
>

This is one of the ways you can forcibly inject this at the link
stage. There are other ways as well (you can compile test such that it
pulls the symbols directly, while still linking against the libc) but
the interesting part is finding a way to combine this technique with
mocking frame works which allow each individual test to set
independent expectations and fake functionality for various system
calls.

-Chandler

Reply all
Reply to author
Forward
0 new messages