libmoost
/home/mhx/git/github/libmoost/test/utils/scope_exit.cpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 // Include boost test framework required headers
00029 #include <boost/test/unit_test.hpp>
00030 #include <boost/test/test_tools.hpp>
00031 
00032 // Include CRT/STL required header(s)
00033 #include <stdexcept>
00034 #include <csignal>
00035 #include <set>
00036 
00037 #include <boost/bind.hpp>
00038 
00039 // Include thrift headers
00040 
00041 // Include application required header(s)
00042 #include "../../include/moost/utils/scope_exit.hpp"
00043 
00044 // Imported required namespace(s)
00045 using namespace moost::utils;
00046 
00047 // Name the test suite
00048 BOOST_AUTO_TEST_SUITE( MoostUtilsScopeExitTest )
00049 
00050 // Define the test fixture
00051 struct Fixture
00052 {
00053    // C_tor
00054    Fixture()
00055    {
00056    }
00057 
00058    // D_tor
00059    ~Fixture()
00060    {
00061    }
00062 };
00063 
00064 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_default_value, Fixture )
00065 {
00066    bool b = false; // default is false
00067    {
00068       scope_exit::type<bool>::set_default_value se(b);
00069       b = true;
00070    }
00071    BOOST_CHECK(!b);
00072 
00073    std::sig_atomic_t sig = 0;
00074    {
00075       scope_exit::type<std::sig_atomic_t>::set_default_value se(sig);
00076       sig = 1;
00077    }
00078    BOOST_CHECK(0 == sig);
00079 }
00080 
00081 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_default_value_cancel, Fixture )
00082 {
00083    bool b = false; // default is false
00084    {
00085       scope_exit::type<bool>::set_default_value se(b);
00086       b = true;
00087       se.cancel();
00088    }
00089    BOOST_CHECK(b);
00090 
00091    std::sig_atomic_t sig = 0;
00092    {
00093       scope_exit::type<std::sig_atomic_t>::set_default_value se(sig);
00094       sig = 1;
00095       se.cancel();
00096    }
00097    BOOST_CHECK(1 == sig);
00098 }
00099 
00100 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_specific_value, Fixture )
00101 {
00102    int i = 0; // specific is false
00103    {
00104       scope_exit::type<int>::set_specific_value se(i, 10);
00105       i = 5;
00106    }
00107    BOOST_CHECK(i == 10);
00108 }
00109 
00110 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_set_specific_value_cancel, Fixture )
00111 {
00112    int i = 0; // specific is false
00113    {
00114       scope_exit::type<int>::set_specific_value se(i, 10);
00115       i = 5;
00116       se.cancel();
00117    }
00118    BOOST_CHECK(i == 5);
00119 }
00120 
00121 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_restore_original_value, Fixture )
00122 {
00123    bool b = true;
00124    {
00125       scope_exit::type<bool>::restore_original_value se(b);
00126       b = false;
00127    }
00128    BOOST_CHECK(b);
00129 
00130    std::sig_atomic_t sig = 1;
00131    {
00132       scope_exit::type<std::sig_atomic_t>::restore_original_value se(sig);
00133       sig = 0;
00134    }
00135    BOOST_CHECK(1 == sig);
00136 }
00137 
00138 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_restore_original_value_cancel, Fixture )
00139 {
00140    bool b = true;
00141    {
00142       scope_exit::type<bool>::restore_original_value se(b);
00143       b = false;
00144       se.cancel();
00145    }
00146    BOOST_CHECK(!b);
00147 
00148    std::sig_atomic_t sig = 1;
00149    {
00150       scope_exit::type<std::sig_atomic_t>::restore_original_value se(sig);
00151       sig = 0;
00152       se.cancel();
00153    }
00154    BOOST_CHECK(0 == sig);
00155 }
00156 
00157 namespace
00158 {
00159    struct Scoped
00160    {
00161       Scoped (std::sig_atomic_t sig) : sig(sig)
00162       {
00163       }
00164 
00165       void operator()()
00166       {
00167          sig = 0;
00168       }
00169 
00170       std::sig_atomic_t sig;
00171    };
00172 }
00173 
00174 
00175 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function_default_, Fixture )
00176 {
00177    Scoped scoped = 0;
00178    {
00179       scope_exit::type<Scoped>::call_member_function se(scoped);
00180       scoped.sig = 1;
00181    }
00182    BOOST_CHECK(0 == scoped.sig);
00183 }
00184 
00185 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function_default_cancel, Fixture )
00186 {
00187    Scoped scoped = 0;
00188    {
00189       scope_exit::type<Scoped>::call_member_function se(scoped);
00190       scoped.sig = 1;
00191       se.cancel();
00192    }
00193    BOOST_CHECK(1 == scoped.sig);
00194 }
00195 
00196 namespace
00197 {
00198    struct ScopedReset
00199    {
00200       ScopedReset (std::sig_atomic_t sig) : sig(sig)
00201       {
00202       }
00203 
00204       void reset()
00205       {
00206          sig = 0;
00207       }
00208 
00209       std::sig_atomic_t sig;
00210    };
00211 }
00212 
00213 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function, Fixture )
00214 {
00215    ScopedReset scoped = 0;
00216    {
00217       scope_exit::type<ScopedReset>::call_member_function se(scoped, &ScopedReset::reset);
00218       scoped.sig = 1;
00219    }
00220    BOOST_CHECK(0 == scoped.sig);
00221 }
00222 
00223 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_member_function_cancel, Fixture )
00224 {
00225    ScopedReset scoped = 0;
00226    {
00227       scope_exit::type<ScopedReset>::call_member_function se(scoped, &ScopedReset::reset);
00228       scoped.sig = 1;
00229       se.cancel();
00230    }
00231    BOOST_CHECK(1 == scoped.sig);
00232 }
00233 
00234 namespace
00235 {
00236    struct ScopedPod
00237    {
00238       std::sig_atomic_t sig;
00239    };
00240 
00241    void scope_reset(ScopedPod & scoped)
00242    {
00243       scoped.sig = 0;
00244    }
00245 
00246    struct scope_reset_functor
00247    {
00248       void operator() (ScopedPod & scoped) const
00249       {
00250          scoped.sig = 0;
00251       }
00252    };
00253 }
00254 
00255 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_ref, Fixture )
00256 {
00257    ScopedPod scoped = { 0 };
00258    {
00259       scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset);
00260       scoped.sig = 1;
00261    }
00262    BOOST_CHECK(0 == scoped.sig);
00263 }
00264 
00265 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_ref_cancel, Fixture )
00266 {
00267    ScopedPod scoped = { 0 };
00268    {
00269       scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset);
00270       scoped.sig = 1;
00271       se.cancel();
00272    }
00273    BOOST_CHECK(1 == scoped.sig);
00274 }
00275 
00276 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_functor_with_ref, Fixture )
00277 {
00278    ScopedPod scoped = { 0 };
00279    {
00280       scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset_functor());
00281       scoped.sig = 1;
00282    }
00283    BOOST_CHECK(0 == scoped.sig);
00284 }
00285 
00286 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_functor_with_ref_cancel, Fixture )
00287 {
00288    ScopedPod scoped = { 0 };
00289    {
00290       scope_exit::type<ScopedPod>::call_free_function_with_ref se(scoped, scope_reset_functor());
00291       scoped.sig = 1;
00292       se.cancel();
00293    }
00294    BOOST_CHECK(1 == scoped.sig);
00295 }
00296 
00297 namespace
00298 {
00299    int global = 0;
00300 
00301    void set_global(int i_)
00302    {
00303       global = i_;
00304    }
00305 
00306    struct set_global_functor
00307    {
00308       void operator()(int i_)
00309       {
00310          global = i_;
00311       }
00312    };
00313 }
00314 
00315 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_val, Fixture )
00316 {
00317    global = 0;
00318    {
00319       scope_exit::type<int>::call_free_function_with_val se(10, set_global);
00320       BOOST_CHECK(0 == global);
00321    }
00322 
00323    BOOST_CHECK(10 == global);
00324 }
00325 
00326 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_free_function_with_val_cancel, Fixture )
00327 {
00328    global = 0;
00329    {
00330       scope_exit::type<int>::call_free_function_with_val se(10, set_global);
00331       BOOST_CHECK(0 == global);
00332       se.cancel();
00333    }
00334 
00335    BOOST_CHECK(0 == global);
00336 }
00337 
00338 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor_with_val, Fixture )
00339 {
00340    global = 0;
00341    {
00342       scope_exit::type<int>::call_free_function_with_val se(10, set_global_functor());
00343       BOOST_CHECK(0 == global);
00344    }
00345 
00346    BOOST_CHECK(10 == global);
00347 }
00348 
00349 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor_with_val_cancel, Fixture )
00350 {
00351    global = 0;
00352    {
00353       scope_exit::type<int>::call_free_function_with_val se(10, set_global_functor());
00354       BOOST_CHECK(0 == global);
00355       se.cancel();
00356    }
00357 
00358    BOOST_CHECK(0 == global);
00359 }
00360 
00361 namespace
00362 {
00363    struct functor
00364    {
00365       functor(int & x): x_(x) {}
00366 
00367       void member_func()
00368       {
00369          x_ = 10;
00370       }
00371 
00372       int & x_;
00373    };
00374 }
00375 
00376 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor, Fixture )
00377 {
00378    int x = 0;
00379 
00380    global = 0;
00381    {
00382       scope_exit::call_functor se(boost::bind(&functor::member_func, functor(x)));
00383       BOOST_CHECK(0 == x);
00384    }
00385 
00386    BOOST_CHECK(10 == x);
00387 }
00388 
00389 BOOST_FIXTURE_TEST_CASE( test_utils_scope_exit_call_functor_cancel, Fixture )
00390 {
00391    int x = 0;
00392 
00393    global = 0;
00394    {
00395       scope_exit::call_functor se(boost::bind(&functor::member_func, functor(x)));
00396       BOOST_CHECK(0 == x);
00397       se.cancel();
00398    }
00399 
00400    BOOST_CHECK(0 == x);
00401 }
00402 
00403 
00404 // Define end of test suite
00405 BOOST_AUTO_TEST_SUITE_END()