10

I am developing an application handling CTRL-C. I am producing a signal handler to shut-down gracefully threads and other resources.

I want to test CTRL-C in different scenarios where my application might be. I know how to setup those for the process under test, but I need a way (in the code of the running test suite) to check whether that condition is reached or not to call exactly CTRL-C.

I work in Linux and I want to run my tests automatically with the help of CPPUNIT. In each of my CTRL-C tests I start the process and then I send CTRL-C using kill function having the PID of the process.

I am using shared memory; once the tested application reaches a condition of my interest or a point when I would like to send CTRL-C, I write a tag or a state into the shared memory. Aat the same time the test suite code running in a different process is continuosly polling the shared memory and once it reads the desired state it send CTRL-C/kill.

Do you think is a good approach or it is usually done in better/effective ways?

Kind Regards

AFG

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
Abruzzo Forte e Gentile
  • 14,423
  • 28
  • 99
  • 173
  • possible duplicate of [Why can't I cause a seg fault?](http://stackoverflow.com/questions/2045314/why-cant-i-cause-a-seg-fault) – Martin York Dec 21 '10 at 20:15

2 Answers2

6

First testing the behavior when some external signal is received does not look like unit testing but like functional testing.

Also, the way you do it also sound too complicated and is likely force some kind of synchronization and hide some behaviors.

On the other hand I do not really have something better to suggest for this kind of tests, this is usually done by external tools in a much less controled way.

kriss
  • 23,497
  • 17
  • 97
  • 116
  • I see what you mean. Somekind of "TOO COMPLICATED" too code against. What Kind of tool do you mean? Are these free/open source? – Abruzzo Forte e Gentile Dec 21 '10 at 16:10
  • 1
    +1 testing signal handlers sounds like functional testing to me too. – Sam Miller Dec 21 '10 at 16:38
  • +1, it is indeed for a functional test - not for an unit test – BЈовић Dec 21 '10 at 17:42
  • I don't understand. Why this type of test should not be in a Unit Test suite? I want to make sure that resources are freed correctly, files storing data to be reused the following time are written correctly ( test what I expect to be written ), even the possibility to restart the application correctly..etc...for me FUNCTIONAL is to make sure that when I press a button to do something on a GUI it actually does. Me personally I would test also what I have also described in a test suite. Don't you? If not can you tell me quickly why? – Abruzzo Forte e Gentile Dec 21 '10 at 17:44
  • The main problem is that the way you test put strong constraints on the timing at wich ctrl+C will be received and the risk is missing existing cases where ressources are not freed correctly. – kriss Jan 12 '11 at 22:40
  • 2
    @abruzzo-forte-e-gentile: unit testing is about calling some function using your programming language internal API. That is not what your test is doing. Functional testing is indeed about user (ie: external world) interaction with your program. Getting a signal is external world interaction, you could even call that a brutal kind of GUI, as could be cases like running your program on a system that does not have enough memory or disk space. Being a functional test does not mean it's not important or do not want to put it in a test suite. – kriss Jan 12 '11 at 22:49
  • @abruzzo-forte-e-gentile: in other words, using CPPUNIT does not mean you are writing a unit test. – kriss Jan 12 '11 at 22:51
  • ( I am going through my responses after few months ) Aftermath of this post and my question: you were right! I achieved What I wanted to do using a mixture of scripts in PERL and SWIG..at the end I wanted to implement some regression test and probing FROM THE OUSTIDE! Thanks a lot for your comments. – Abruzzo Forte e Gentile Aug 24 '11 at 21:44
3

Introduce a level of indirection.

  1. Place your high-level program code behind a Facade (I use a class named Program).
  2. Have that Facade provide a shutdown() method, which performs all of the shutdown operation except calling std::exit().
  3. Unit test that shutdown() method as you would any other method.
  4. Have the signal handler delegate to that shutdown() method for the static Program object that represents your entire program then call std::exit(). This is the only part you can not unit test.
Raedwald
  • 46,613
  • 43
  • 151
  • 237
  • Hi and thanks. I already do something very similar. My main() function basically creates an instance of what is for you the class 'Program'. If I use it inside my unit test and I setup a signal handler for the 'Program; class, then I will setup a signal handler also for the test runner and I would like to avoid that and trying to have as the real case i.e. a separate process where I can call from the outside kill. Anyway I will try to dig better the idea of a static shutdown(). For this I have to review signal handling. They are very strict requirements. – Abruzzo Forte e Gentile Dec 21 '10 at 23:37
  • If I follow your approach I have to make sure to restore the original signal handler during setUp()/tearDown() of the test suite. I think it might be worth trying. – Abruzzo Forte e Gentile Dec 21 '10 at 23:38
  • 1
    You can split your test requirements in two: does receipt of a SIGTERM cause a controlled shutdown, and does a controlled shutdown correctly free resources, close files etc. Unit testing can help you with the second, by testing your shutdown() method, but it is unsuitable for the first. – Raedwald Dec 22 '10 at 10:48
  • Just a note With a big delay ( I am going through all response of last period ) to tell you how did go. Your suggestion is fine, but for impractical reasons I left behind CPPUNIT to reach what is more closed to functional testing ( as suggested by kriss ). I achieved a decent level of regressing embedding everything in PERL ( including your way of shutting down the app + calling SIGINT from the outside ). – Abruzzo Forte e Gentile Aug 24 '11 at 21:42