| 1 | /* |
| 2 | The software in this package is distributed under the GNU General |
| 3 | Public License version 2 (with a special exception described below). |
| 4 | |
| 5 | A copy of GNU General Public License (GPL) is included in this distribution, |
| 6 | in the file COPYING.GPL. |
| 7 | |
| 8 | As a special exception, if other files instantiate templates or use macros |
| 9 | or inline functions from this file, or you compile this file and link it |
| 10 | with other works to produce a work based on this file, this file |
| 11 | does not by itself cause the resulting work to be covered |
| 12 | by the GNU General Public License. |
| 13 | |
| 14 | However the source code for this file must still be made available |
| 15 | in accordance with section (3) of the GNU General Public License. |
| 16 | |
| 17 | This exception does not invalidate any other reasons why a work based |
| 18 | on this file might be covered by the GNU General Public License. |
| 19 | */ |
| 20 | /** @file |
| 21 | * |
| 22 | * (c) Copyright 2008 by Intra2net AG |
| 23 | */ |
| 24 | |
| 25 | #include <string> |
| 26 | #include <iostream> |
| 27 | #include <fstream> |
| 28 | #include <iomanip> |
| 29 | #include <list> |
| 30 | #include <vector> |
| 31 | #include <set> |
| 32 | |
| 33 | #define BOOST_TEST_DYN_LINK |
| 34 | #include <boost/test/unit_test.hpp> |
| 35 | |
| 36 | #include <i2n_global_config.hpp> |
| 37 | #include <filefunc.hxx> |
| 38 | #include <logfunc.hpp> |
| 39 | |
| 40 | |
| 41 | #ifdef NOISEDEBUG |
| 42 | #define DOUT(msg) std::cout << msg << std::endl |
| 43 | #else |
| 44 | #define DOUT(msg) do {} while (0) |
| 45 | #endif |
| 46 | |
| 47 | |
| 48 | using namespace I2n; |
| 49 | |
| 50 | class TestGlobalConfigFixture |
| 51 | { |
| 52 | protected: |
| 53 | std::set<std::string> used_check_files; |
| 54 | |
| 55 | std::string getCheckFilepath(std::string tag) |
| 56 | { |
| 57 | std::string result; |
| 58 | result= "__unittest__" + tag + ".dat"; |
| 59 | used_check_files.insert(result); |
| 60 | return result; |
| 61 | } // eo get_check_file_path |
| 62 | |
| 63 | void removeCheckFiles() |
| 64 | { |
| 65 | for(std::set<std::string>::iterator it= used_check_files.begin(); |
| 66 | it != used_check_files.end(); |
| 67 | ++it) |
| 68 | { |
| 69 | std::string filepath(*it); |
| 70 | if (path_exists(filepath)) |
| 71 | { |
| 72 | unlink(filepath); |
| 73 | } |
| 74 | } |
| 75 | used_check_files.clear(); |
| 76 | } // eo removeCheckFiles |
| 77 | |
| 78 | public: |
| 79 | TestGlobalConfigFixture() |
| 80 | { |
| 81 | //Logger::enable_stderr_log(true); |
| 82 | //Logger::set_log_level( Logger::LogLevel::Debug ); |
| 83 | used_check_files.clear(); |
| 84 | } |
| 85 | |
| 86 | ~TestGlobalConfigFixture() |
| 87 | { |
| 88 | removeCheckFiles(); |
| 89 | //Logger::enable_stderr_log(false); |
| 90 | //Logger::set_log_level( Logger::LogLevel::Error ); |
| 91 | } |
| 92 | }; |
| 93 | |
| 94 | BOOST_FIXTURE_TEST_SUITE(TestGlobalConfig, TestGlobalConfigFixture) |
| 95 | |
| 96 | BOOST_AUTO_TEST_CASE(Basics) |
| 97 | { |
| 98 | std::string filename= getCheckFilepath("Basics"); |
| 99 | std::string cfg( |
| 100 | "a path= /var/run/my.pid\n" |
| 101 | "\n" |
| 102 | "[sec1]\n" |
| 103 | "s1 = ein Text\n" |
| 104 | "i1 = 100\n" |
| 105 | "f1 = 2.5\n" |
| 106 | ); |
| 107 | std::string cfg2( |
| 108 | "a path= /var/run/my.pid\n" |
| 109 | "\n" |
| 110 | "[sec1]\n" |
| 111 | "s1 = ein Text\n" |
| 112 | "i1 = 10\n" |
| 113 | "f1 = 3.5\n" |
| 114 | "i2 = 010\n" |
| 115 | "i3 = 0x10\n" |
| 116 | ); |
| 117 | bool res= write_file(filename,cfg); |
| 118 | BOOST_CHECK_EQUAL( true, res ); |
| 119 | |
| 120 | Config::Var<std::string> var_s1("sec1", "s1", "nix"); |
| 121 | |
| 122 | res= Config::set_config_file(filename); |
| 123 | BOOST_CHECK_EQUAL( true, res ); |
| 124 | |
| 125 | BOOST_CHECK_EQUAL( std::string("ein Text"), (std::string)var_s1 ); |
| 126 | |
| 127 | Config::Var<int> var_i1("sec1","i1",0); |
| 128 | BOOST_CHECK_EQUAL( 100, var_i1() ); |
| 129 | |
| 130 | Config::Var<double> var_f1("sec1","f1", 0.0); |
| 131 | BOOST_CHECK_EQUAL( 2.5, var_f1() ); |
| 132 | |
| 133 | Config::Var<const std::string> pid_path("a path", "/var/run/x.pid"); |
| 134 | BOOST_CHECK_EQUAL( std::string("/var/run/my.pid"), pid_path() ); |
| 135 | |
| 136 | // try an already used var again as different type: |
| 137 | Config::Var<std::string> var_i1s("sec1","i1","0"); |
| 138 | BOOST_CHECK_EQUAL( std::string("100"), var_i1s() ); |
| 139 | |
| 140 | |
| 141 | // make a copy from a given var: |
| 142 | Config::Var< int > var_i1_2 ( var_i1 ); |
| 143 | BOOST_CHECK_EQUAL( 100, var_i1_2() ); |
| 144 | |
| 145 | // now write a modified config |
| 146 | res= write_file(filename,cfg2); |
| 147 | BOOST_CHECK_EQUAL( true, res ); |
| 148 | |
| 149 | // .. and reload. |
| 150 | res= Config::reload(); |
| 151 | BOOST_CHECK_EQUAL( true, res ); |
| 152 | |
| 153 | // check if the (right) vars changed.. |
| 154 | |
| 155 | BOOST_CHECK_EQUAL( std::string("ein Text"), (std::string)var_s1 ); |
| 156 | BOOST_CHECK_EQUAL( 10, var_i1() ); |
| 157 | BOOST_CHECK_EQUAL( std::string("10"), var_i1s() ); |
| 158 | BOOST_CHECK_EQUAL( 3.5, var_f1() ); |
| 159 | BOOST_CHECK_EQUAL( 10, var_i1_2() ); |
| 160 | |
| 161 | // check for the new vars |
| 162 | |
| 163 | Config::Var<int, Config::AutoIntConverter<int> > var_i2("sec1","i2",0); |
| 164 | BOOST_CHECK_EQUAL( 8, var_i2() ); |
| 165 | |
| 166 | Config::Var<int, Config::AutoIntConverter<int> > var_i3("sec1","i3",0); |
| 167 | BOOST_CHECK_EQUAL( 16, var_i3() ); |
| 168 | } // eo Basics |
| 169 | |
| 170 | |
| 171 | |
| 172 | BOOST_AUTO_TEST_CASE(MultipleValues) |
| 173 | { |
| 174 | std::string filename= getCheckFilepath("MultipleValues"); |
| 175 | std::string cfg( |
| 176 | "[sec1]\n" |
| 177 | "g1 = 11\n" |
| 178 | "g1 = 12\n" |
| 179 | "g2 = 21\n" |
| 180 | "g2 = 22\n" |
| 181 | "g1 = 13\n" |
| 182 | "g1 = 14\n" |
| 183 | ); |
| 184 | std::string cfg2( |
| 185 | "[sec1]\n" |
| 186 | "g1 = 11\n" |
| 187 | "g1 = 12\n" |
| 188 | "g2 = 20\n" |
| 189 | "g2 = 22\n" |
| 190 | "g1 = 13\n" |
| 191 | ); |
| 192 | |
| 193 | bool res= write_file(filename,cfg); |
| 194 | BOOST_CHECK_EQUAL( true, res ); |
| 195 | |
| 196 | typedef std::list< int > IntList; |
| 197 | typedef std::vector< int > IntVector; |
| 198 | |
| 199 | res= Config::set_config_file(filename); |
| 200 | BOOST_CHECK_EQUAL( true, res ); |
| 201 | |
| 202 | Config::Var< IntList > list1("sec1","g1", IntList()); |
| 203 | Config::Var< IntList > list2("sec1","g2", IntList()); |
| 204 | |
| 205 | BOOST_CHECK_EQUAL( 4u, list1().size() ); |
| 206 | BOOST_CHECK_EQUAL( 2u, list2().size() ); |
| 207 | |
| 208 | BOOST_CHECK_EQUAL( 11, list1().front() ); |
| 209 | BOOST_CHECK_EQUAL( 14, list1().back() ); |
| 210 | BOOST_CHECK_EQUAL( 21, list2().front() ); |
| 211 | BOOST_CHECK_EQUAL( 22, list2().back() ); |
| 212 | |
| 213 | Config::Var< IntVector > vector1("sec1","g1", IntVector()); |
| 214 | Config::Var< IntVector > vector2("sec1","g2", IntVector()); |
| 215 | |
| 216 | BOOST_CHECK_EQUAL( 4u, vector1().size() ); |
| 217 | BOOST_CHECK_EQUAL( 2u, vector2().size() ); |
| 218 | |
| 219 | BOOST_CHECK_EQUAL( 11, vector1().front() ); |
| 220 | BOOST_CHECK_EQUAL( 14, vector1().back() ); |
| 221 | BOOST_CHECK_EQUAL( 21, vector2().front() ); |
| 222 | BOOST_CHECK_EQUAL( 22, vector2().back() ); |
| 223 | |
| 224 | // now write a modified config |
| 225 | res= write_file(filename,cfg2); |
| 226 | BOOST_CHECK_EQUAL( true, res ); |
| 227 | |
| 228 | // .. and reload. |
| 229 | res= Config::reload(); |
| 230 | BOOST_CHECK_EQUAL( true, res ); |
| 231 | |
| 232 | // check if the (right) vars changed.. |
| 233 | |
| 234 | BOOST_CHECK_EQUAL( 3u, list1().size() ); |
| 235 | BOOST_CHECK_EQUAL( 2u, list2().size() ); |
| 236 | |
| 237 | BOOST_CHECK_EQUAL( 11, list1().front() ); |
| 238 | BOOST_CHECK_EQUAL( 13, list1().back() ); |
| 239 | BOOST_CHECK_EQUAL( 20, list2().front() ); |
| 240 | BOOST_CHECK_EQUAL( 22, list2().back() ); |
| 241 | |
| 242 | } // eo MultipleValues |
| 243 | |
| 244 | |
| 245 | BOOST_AUTO_TEST_CASE(MultipleValuesVanish) |
| 246 | { |
| 247 | std::string filename= getCheckFilepath("MultipleValuesVanish"); |
| 248 | std::string cfg( |
| 249 | "[sec1]\n" |
| 250 | "g1 = 11\n" |
| 251 | "g1 = 12\n" |
| 252 | "g2 = 21\n" |
| 253 | ); |
| 254 | std::string cfg2( |
| 255 | "[sec1]\n" |
| 256 | "g1 = 11\n" |
| 257 | ); |
| 258 | |
| 259 | bool res= write_file(filename,cfg); |
| 260 | BOOST_CHECK_EQUAL( true, res ); |
| 261 | |
| 262 | typedef std::list< int > IntList; |
| 263 | typedef std::vector< int > IntVector; |
| 264 | |
| 265 | res= Config::set_config_file(filename); |
| 266 | BOOST_CHECK_EQUAL( true, res ); |
| 267 | |
| 268 | Config::Var< IntList > list1("sec1","g1", IntList()); |
| 269 | Config::Var< IntList > list2("sec1","g2", IntList()); |
| 270 | |
| 271 | BOOST_CHECK_EQUAL( 2u, list1().size() ); |
| 272 | BOOST_CHECK_EQUAL( 1u, list2().size() ); |
| 273 | |
| 274 | BOOST_CHECK_EQUAL( 11, list1().front() ); |
| 275 | BOOST_CHECK_EQUAL( 12, list1().back() ); |
| 276 | BOOST_CHECK_EQUAL( 21, list2().front() ); |
| 277 | BOOST_CHECK_EQUAL( 21, list2().back() ); |
| 278 | |
| 279 | Config::Var< IntVector > vector1("sec1","g1", IntVector()); |
| 280 | Config::Var< IntVector > vector2("sec1","g2", IntVector()); |
| 281 | |
| 282 | BOOST_CHECK_EQUAL( 2u, vector1().size() ); |
| 283 | BOOST_CHECK_EQUAL( 1u, vector2().size() ); |
| 284 | |
| 285 | BOOST_CHECK_EQUAL( 11, vector1().front() ); |
| 286 | BOOST_CHECK_EQUAL( 12, vector1().back() ); |
| 287 | BOOST_CHECK_EQUAL( 21, vector2().front() ); |
| 288 | BOOST_CHECK_EQUAL( 21, vector2().back() ); |
| 289 | |
| 290 | // now write a modified config |
| 291 | res= write_file(filename,cfg2); |
| 292 | BOOST_CHECK_EQUAL( true, res ); |
| 293 | |
| 294 | // .. and reload. |
| 295 | res= Config::reload(); |
| 296 | BOOST_CHECK_EQUAL( true, res ); |
| 297 | |
| 298 | // check if the (right) vars changed.. |
| 299 | |
| 300 | BOOST_CHECK_EQUAL( 1u, list1().size() ); |
| 301 | BOOST_CHECK_EQUAL( 0u, list2().size() ); |
| 302 | |
| 303 | BOOST_CHECK_EQUAL( 11, list1().front() ); |
| 304 | |
| 305 | } // eo MultipleValuesVanish |
| 306 | |
| 307 | BOOST_AUTO_TEST_SUITE_END() |