tests/test_network_worker.cpp

Go to the documentation of this file.
00001 /* $Id: test_network_worker.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Pauli Nieminen <paniemin@cc.hut.fi>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #define GETTEXT_DOMAIN "wesnoth-test"
00017 
00018 #include <boost/test/unit_test.hpp>
00019 
00020 
00021 #include "utils/auto_parameterized.hpp"
00022 #include "utils/predicate.hpp"
00023 
00024 #include "network_worker.hpp"
00025 #include "thread.hpp"
00026 #include "filesystem.hpp"
00027 
00028 #include "config.hpp"
00029 #include "game_config.hpp"
00030 
00031 /**
00032  * Test networking to prevent bugs there.
00033  * Try to create all kind of unlikely error conditions
00034  * Some test should lock management_mutex from worker to settup stress test
00035  * It is like that this will need some threading also :(
00036  */
00037 
00038 BOOST_AUTO_TEST_SUITE( test_network )
00039 
00040 const int TEST_PORT = 15010;
00041 const int MIN_THREADS = 1;
00042 const int MAX_THREADS = 5;
00043 const std::string LOCALHOST = "localhost";
00044 
00045 
00046 network::manager* wes_manager;
00047 network::server_manager* wes_server;
00048 
00049 network::connection client_client1;
00050 network::connection client_client2;
00051 
00052 network::connection server_client1;
00053 network::connection server_client2;
00054 
00055 
00056 BOOST_AUTO_TEST_CASE( test_connect )
00057 {
00058     int connections = network::nconnections();
00059 
00060     BOOST_WARN_MESSAGE(connections == 0, "There is open "<< connections <<" connections before test!");
00061     BOOST_CHECK_MESSAGE(wes_manager = new network::manager(MIN_THREADS,MAX_THREADS), "network::manager failed to initialize");
00062 
00063     BOOST_CHECK_MESSAGE(wes_server = new network::server_manager(TEST_PORT,network::server_manager::MUST_CREATE_SERVER),
00064             "network::server_manager failed to initialize");
00065     BOOST_REQUIRE_MESSAGE(wes_server->is_running(), "Can't start server!");
00066 
00067     client_client1 = network::connect(LOCALHOST, TEST_PORT);
00068 
00069     BOOST_CHECK_MESSAGE(client_client1 > 0, "Can't connect to server");
00070 
00071     server_client1 = network::accept_connection();
00072 
00073     BOOST_CHECK_MESSAGE(server_client1 > 0, "Can't accept connection");
00074 
00075 
00076 }
00077 
00078 template<class T>
00079 static network::connection receive(T& cfg, int max_tries = 100)
00080 {
00081     network::connection receive_con;
00082     while ((receive_con = network::receive_data(cfg)) == network::null_connection)
00083     {
00084         // loop untill data is received
00085         SDL_Delay(50);
00086         if (--max_tries <= 0)
00087         {
00088             BOOST_WARN_MESSAGE(max_tries > 0,"receiving data took too long. Preventing for ever loop");
00089             break;
00090         }
00091     }
00092     return receive_con;
00093 }
00094 
00095 BOOST_AUTO_TEST_CASE( test_send_client )
00096 {
00097     config cfg_send;
00098     config& child = cfg_send.add_child("test_client_send");
00099 
00100     child["test"] = "yes!";
00101     cfg_send["test_running"] = true;
00102     network::send_data(cfg_send, client_client1);
00103 
00104     network::connection receive_from;
00105     config received;
00106 
00107     receive_from = receive(received);
00108 
00109     BOOST_CHECK_MESSAGE( receive_from == server_client1, "Received data is not from test client 1" );
00110 
00111     BOOST_CHECK_EQUAL(cfg_send, received);
00112 
00113 }
00114 
00115 
00116 class connect_aborter : public threading::waiter
00117 {
00118 public:
00119     connect_aborter() : start_(SDL_GetTicks())
00120     {}
00121     ACTION process();
00122 
00123 private:
00124     size_t start_;
00125 };
00126 
00127 connect_aborter::ACTION connect_aborter::process()
00128 {
00129     // Abort connection after 5 ms
00130     if(SDL_GetTicks() - start_ >= 5) {
00131         return ABORT;
00132     } else {
00133         return WAIT;
00134     }
00135 }
00136 
00137 #if 0
00138 BOOST_AUTO_TEST_CASE( test_sdl_thread_wait_crash )
00139 {
00140 
00141     delete wes_server;
00142     wes_server = 0;
00143     delete wes_manager;
00144     wes_manager = 0;
00145     BOOST_CHECK_MESSAGE(wes_manager == 0, "network::manager nono zero after delete");
00146 
00147     BOOST_CHECK_MESSAGE(wes_manager = new network::manager(MIN_THREADS,MAX_THREADS), "network::manager failed to initialize");
00148     BOOST_CHECK_THROW(client_client1 = network::connect(LOCALHOST, TEST_PORT), network::error);
00149     BOOST_CHECK_MESSAGE(client_client1 > 0, "Can't connect to server");
00150     delete wes_manager;
00151     wes_manager = 0;
00152     BOOST_CHECK_MESSAGE(wes_manager = new network::manager(MIN_THREADS,MAX_THREADS), "network::manager failed to initialize");
00153 
00154     connect_aborter aborter;
00155     BOOST_CHECK_MESSAGE((client_client1 = network::connect("server.wesnoth.org", 15000, aborter)) == 0, "Connection create but not shoul");
00156     delete wes_manager;
00157 
00158     BOOST_CHECK_MESSAGE(wes_manager = new network::manager(MIN_THREADS,MAX_THREADS), "network::manager failed to initialize");
00159     BOOST_CHECK_MESSAGE(wes_server = new network::server_manager(TEST_PORT,network::server_manager::MUST_CREATE_SERVER), "");
00160     BOOST_CHECK_MESSAGE((client_client1 = network::connect(LOCALHOST, TEST_PORT, aborter)) == 0, "Connection create but not shoul");
00161     delete wes_manager;
00162 
00163     wes_manager = new network::manager(MIN_THREADS,MAX_THREADS);
00164     client_client1 = network::connect(LOCALHOST, TEST_PORT);
00165     BOOST_CHECK_MESSAGE(client_client1 > 0, "Can't connect to server");
00166     delete wes_server;
00167     delete wes_manager;
00168     wes_manager = new network::manager(MIN_THREADS,MAX_THREADS);
00169     wes_server = new network::server_manager(TEST_PORT,network::server_manager::MUST_CREATE_SERVER);
00170 }
00171 #endif
00172 
00173 // Use 1kb, 500kb and 10Mb files for testing
00174 struct sendfile_param {
00175     sendfile_param(size_t size, bool system) : size_(size), system_(system) {}
00176     size_t size_;
00177     bool system_;
00178 };
00179 
00180 sendfile_param sendfile_sizes[] = {sendfile_param(1*1024,true),
00181                                    sendfile_param(5*1024*1024,true),
00182                                    sendfile_param(1*1024,false),
00183                                    sendfile_param(5*1024*1024,false)};
00184 
00185 static std::string create_random_sendfile(size_t size)
00186 {
00187     char buffer[1024];
00188     const int buffer_size = sizeof(buffer)/sizeof(buffer[0]);
00189     int *begin = reinterpret_cast<int*>(&buffer[0]);
00190     int *end = begin + sizeof(buffer)/sizeof(int);
00191     std::string filename = "sendfile.tmp";
00192     scoped_ostream file = ostream_file(filename);
00193     std::generate(begin,end,std::rand);
00194     while( size > 0
00195         && !file->bad())
00196     {
00197         file->write(buffer, buffer_size);
00198         size -= buffer_size;
00199     }
00200     return filename;
00201 }
00202 
00203 static void delete_random_sendfile(const std::string& file)
00204 {
00205     delete_directory(file);
00206 }
00207 
00208 template<class T>
00209 class auto_resetter {
00210     T& value_to_change_;
00211     T old_val_;
00212     public:
00213     auto_resetter(const T& new_value, T& value_to_change) : value_to_change_(value_to_change), old_val_(value_to_change)
00214     {
00215         value_to_change_ = new_value;
00216     }
00217     ~auto_resetter()
00218     {
00219         value_to_change_ = old_val_;
00220     }
00221 };
00222 
00223 WESNOTH_PARAMETERIZED_TEST_CASE( test_multi_sendfile, sendfile_param, sendfile_sizes, size )
00224 {
00225     auto_resetter<std::string> path("", game_config::path);
00226     network::set_raw_data_only();
00227     std::string file = create_random_sendfile(size.size_);
00228     network_worker_pool::set_use_system_sendfile(size.system_);
00229 
00230     network::connection cl_client1, se_client1;
00231     network::connection cl_client2, se_client2;
00232     network::connection cl_client3, se_client3;
00233 
00234     BOOST_CHECK_MESSAGE((cl_client1 = network::connect(LOCALHOST, TEST_PORT)) > 0, "Can't connect to server!");
00235     BOOST_CHECK_MESSAGE((se_client1 = network::accept_connection()) > 0, "Coulnd't accept new connection");
00236     BOOST_CHECK_MESSAGE((cl_client2 = network::connect(LOCALHOST, TEST_PORT)) > 0, "Can't connect to server!");
00237     BOOST_CHECK_MESSAGE((se_client2 = network::accept_connection()) > 0, "Coulnd't accept new connection");
00238     BOOST_CHECK_MESSAGE((cl_client3 = network::connect(LOCALHOST, TEST_PORT)) > 0, "Can't connect to server!");
00239     BOOST_CHECK_MESSAGE((se_client3 = network::accept_connection()) > 0, "Coulnd't accept new connection");
00240 
00241     network::send_file(file, cl_client1);
00242     network::send_file(file, cl_client2);
00243     network::send_file(file, cl_client3);
00244 
00245     std::vector<char> data;
00246 
00247     BOOST_CHECK_PREDICATE(test_utils::one_of<network::connection> , (receive(data,500))(3)(se_client1)(se_client2)(se_client3));
00248     BOOST_CHECK_EQUAL(data.size(), static_cast<size_t>(file_size(file)));
00249     BOOST_CHECK_PREDICATE(test_utils::one_of<network::connection> , (receive(data,500))(3)(se_client1)(se_client2)(se_client3));
00250     BOOST_CHECK_EQUAL(data.size(), static_cast<size_t>(file_size(file)));
00251     BOOST_CHECK_PREDICATE(test_utils::one_of<network::connection> , (receive(data,500))(3)(se_client1)(se_client2)(se_client3));
00252 
00253     BOOST_CHECK_EQUAL(data.size(), static_cast<size_t>(file_size(file)));
00254 
00255     network::disconnect(cl_client1);
00256     network::disconnect(cl_client2);
00257     network::disconnect(cl_client3);
00258 
00259     BOOST_CHECK_THROW(receive(data),network::error);
00260     BOOST_CHECK_THROW(receive(data),network::error);
00261     BOOST_CHECK_THROW(receive(data),network::error);
00262 
00263     delete_random_sendfile(file);
00264 }
00265 
00266 #if 0
00267 BOOST_AUTO_TEST_CASE( test_multiple_connections )
00268 {
00269 }
00270 
00271 BOOST_AUTO_TEST_CASE( test_cancel_transfer )
00272 {
00273 }
00274 
00275 BOOST_AUTO_TEST_CASE( test_detect_errors )
00276 {
00277 }
00278 
00279 BOOST_AUTO_TEST_CASE( test_broken_data )
00280 {
00281 }
00282 
00283 BOOST_AUTO_TEST_CASE( test_config_with_macros )
00284 {
00285 }
00286 
00287 BOOST_AUTO_TEST_CASE( test_disconnect )
00288 {
00289     network::disconnect(client_client1);
00290     network::disconnect(server_client1);
00291 }
00292 #endif
00293 BOOST_AUTO_TEST_CASE( test_shutdown )
00294 {
00295     delete wes_server;
00296     BOOST_CHECK_MESSAGE(true,"Not true");
00297     delete wes_manager;
00298 }
00299 
00300 BOOST_AUTO_TEST_SUITE_END()
00301 /* vim: set ts=4 sw=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:12 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs