10aeff542c098e5b6c2ecfd07039b0ff57d7ef7d
[libcds.git] / test / include / cds_test / stress_test.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13     list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16     this list of conditions and the following disclaimer in the documentation
17     and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSTEST_STRESS_TEST_H
32 #define CDSTEST_STRESS_TEST_H
33
34 #include <map>
35 #include <cds_test/fixture.h>
36 #include <cds_test/thread.h>
37
38 namespace cds_test {
39
40     // Test configuration
41     class config
42     {
43     public:
44         std::string get( const char * pszParamName, const char * pszDefVal = NULL ) const
45         {
46             std::string strParamName( pszParamName );
47             auto it = m_Cfg.find( strParamName );
48             if ( it == m_Cfg.end() )
49                 return std::string( pszDefVal ); // param not found -> returns default value
50             return it->second;
51         }
52
53         int get_int( const char * pszParamName, int defVal = 0 ) const
54         {
55             std::string strParamName( pszParamName );
56             cfg_map::const_iterator it = m_Cfg.find( strParamName );
57             if ( it == m_Cfg.end() )
58                 return defVal; // param not found -> returns default value
59             return atoi( it->second.c_str());
60         }
61
62         unsigned int get_uint( const char * pszParamName, unsigned int defVal = 0 ) const
63         {
64             std::string strParamName( pszParamName );
65             cfg_map::const_iterator it = m_Cfg.find( strParamName );
66             if ( it == m_Cfg.end() )
67                 return defVal; // param not found -> returns default value
68             return static_cast<unsigned int>( strtoul( it->second.c_str(), NULL, 10 ));
69         }
70
71         long get_long( const char * pszParamName, long defVal = 0 ) const
72         {
73             std::string strParamName( pszParamName );
74             cfg_map::const_iterator it = m_Cfg.find( strParamName );
75             if ( it == m_Cfg.end() )
76                 return defVal; // param not found -> returns default value
77             return strtol( it->second.c_str(), NULL, 10 );
78         }
79
80         unsigned long get_ulong( const char * pszParamName, unsigned long defVal = 0 ) const
81         {
82             std::string strParamName( pszParamName );
83             cfg_map::const_iterator it = m_Cfg.find( strParamName );
84             if ( it == m_Cfg.end() )
85                 return defVal; // param not found -> returns default value
86             return strtoul( it->second.c_str(), NULL, 10 );
87         }
88
89         size_t get_size_t( const char * pszParamName, size_t defVal = 0 ) const
90         {
91             std::string strParamName( pszParamName );
92             cfg_map::const_iterator it = m_Cfg.find( strParamName );
93             if ( it == m_Cfg.end() )
94                 return defVal; // param not found -> returns default value
95             return static_cast<size_t>( strtoul( it->second.c_str(), NULL, 10 ));
96         }
97
98         bool get_bool( const char * pszParamName, bool defVal = false ) const
99         {
100             std::string strParamName( pszParamName );
101             cfg_map::const_iterator it = m_Cfg.find( strParamName );
102             if ( it == m_Cfg.end() )
103                 return defVal; // param not found -> returns default value
104             return !( it->second.empty() 
105                    || it->second == "0" 
106                    || it->second == "false"
107                    || it->second == "no"
108                    );
109         }
110
111     private:
112         typedef std::map< std::string, std::string >  cfg_map;
113         cfg_map m_Cfg; // map param_name => value
114
115         friend class config_file;
116     };
117
118     struct property_stream;
119
120     template <typename T>
121     static inline property_stream& operator <<( property_stream& s, std::pair<char const *, T > prop )
122     {
123         std::stringstream ss;
124         ss << prop.second;
125         ::testing::Test::RecordProperty( prop.first, ss.str().c_str());
126         return s;
127     }
128
129     template <typename T>
130     static inline property_stream& operator <<( property_stream& s, std::pair<std::string, T > prop )
131     {
132         std::stringstream ss;
133         ss << prop.second;
134         ::testing::Test::RecordProperty( prop.first.c_str(), ss.str().c_str() );
135         return s;
136     }
137
138     static inline property_stream& operator <<( property_stream& s, std::pair<char const *, std::chrono::milliseconds > prop )
139     {
140         std::stringstream ss;
141         ss << prop.second.count();
142         ::testing::Test::RecordProperty( prop.first, ss.str().c_str() );
143         return s;
144     }
145
146 #define CDSSTRESS_STAT_OUT_( name, val ) std::make_pair( name, val )
147 #define CDSSTRESS_STAT_OUT( s, field ) CDSSTRESS_STAT_OUT_( "stat." #field, s.field.get())
148
149     class stress_fixture : public fixture
150     {
151     protected:
152         stress_fixture()
153             : m_thread_pool( *this )
154         {}
155
156         //static void SetUpTestCase();\r
157         //static void TearDownTestCase();\r
158 \r
159         thread_pool& get_pool()\r
160         {\r
161             return m_thread_pool;\r
162         }\r
163 \r
164         static property_stream& propout();\r
165 \r
166     public:\r
167         static config const& get_config( char const * slot );\r
168         static config const& get_config( std::string const& slot );\r
169 \r
170     private:\r
171         thread_pool     m_thread_pool;\r
172     };
173
174
175     // Internal functions
176     void init_config( int argc, char **argv );
177
178 } // namespace cds_test
179
180 #endif // CDSTEST_FIXTURE_H