Changeset 788

Show
Ignore:
Timestamp:
09/23/08 21:20:08 (9 months ago)
Author:
raggi
Message:

Merge of branches/raggi
Most notable work and patches by Aman Gupta, Roger Pack, and James Tucker.
Patches / Tickets also submitted by: Jeremy Evans, aanand, darix, mmmurf,
danielaquino, macournoyer.

  • Moved docs into docs/ dir
  • Major refactor of rakefile, added generic rakefile helpers in tasks
  • Added example CPP build rakefile in tasks/cpp.rake
  • Moved rake tests out to tasks/tests.rake
  • Added svn ignores where appropriate
  • Fixed jruby build on older java platforms
  • Gem now builds from Rakefile rather than directly via extconf
  • Gem unified for jruby, C++ and pure ruby.
  • Correction for pure C++ build, removing ruby dependency
  • Fix for CYGWIN builds on ipv6
  • Major refactor for extconf.rb
  • Working mingw builds
  • extconf optionally uses pkg_config over manual configuration
  • extconf builds for 1.9 on any system that has 1.9
  • extconf no longer links pthread explicitly
  • looks for kqueue on all *nix systems
  • better error output on std::runtime_error, now says where it came from
  • Fixed some tests on jruby
  • Added test for general send_data flaw, required for a bugfix in jruby build
  • Added timeout to epoll tests
  • Added fixes for java reactor ruby api
  • Small addition of some docs in httpclient.rb and httpcli2.rb
  • Some refactor and fixes in smtpserver.rb
  • Added parenthesis where possible to avoid excess ruby warnings
  • Refactor of $eventmachine_library logic for accuracy and maintenance, jruby
  • EM::start_server now supports unix sockets
  • EM::connect now supports unix sockets
  • EM::defer @threadqueue now handled more gracefully
  • Added better messages on exceptions raised
  • Fix edge case in timer fires
  • Explicitly require buftok.rb
  • Add protocols to autoload, rather than require them all immediately
  • Fix a bug in pr_eventmachine for outbound_q
  • Refactors to take some of the use of defer out of tests.
  • Fixes in EM.defer under start/stop conditions. Reduced scope of threads.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk

    • Property svn:ignore set to
      pkg
      rdoc

      ext/Makefile

      ext/*.bundle
      lib/*.bundle
      ext/*.dll
      lib/*.dll
      ext/*.so
      lib/*.so
      ext/*.jar
      lib/*.jar

      java/src/com/rubyeventmachine/*.class

      ext/*.o
      **/*.log
  • trunk/docs/ChangeLog

    r772 r788  
    12712728Aug08: Added a patch by tmm1 to fix a longstanding problem with Java 
    128128data-sends. 
     12913Sep08: Added LineText2#set_binary_mode, a back-compatibility alias. 
     13013Sep08: Modified the load order of protocol libraries in eventmachine.rb 
     131        to permit a modification of HeaderAndContentProtocol. 
     13213Sep08: Modified HeaderAndContent to use LineText2, which is less buggy 
     133        than LineAndTextProtocol. This change may be reversed if we can fix 
     134        the bugs in buftok. 
     13513Sep08: Improved the password handling in the Postgres protocol handler. 
     13615Sep08: Added attach/detach, contributed by Aman Gupta (tmm1) and Riham Aldakkak, 
     137        to support working with file descriptors not created in the reactor. 
     13816Sep08: Added an optional version string to the HTTP client. This is a hack 
     139        that allows a client to specify a version 1.0 request, which 
     140        keeps the server from sending a chunked response. The right way to 
     141        solve this, of course, is to support chunked responses. 
     14223Sep08: ChangeLog Summary for Merge of branches/raggi 
     143Most notable work and patches by Aman Gupta, Roger Pack, and James Tucker.  
     144Patches / Tickets also submitted by: Jeremy Evans, aanand, darix, mmmurf,  
     145danielaquino, macournoyer. 
     146 - Moved docs into docs/ dir 
     147 - Major refactor of rakefile, added generic rakefile helpers in tasks 
     148 - Added example CPP build rakefile in tasks/cpp.rake 
     149 - Moved rake tests out to tasks/tests.rake 
     150 - Added svn ignores where appropriate 
     151 - Fixed jruby build on older java platforms 
     152 - Gem now builds from Rakefile rather than directly via extconf 
     153 - Gem unified for jruby, C++ and pure ruby. 
     154 - Correction for pure C++ build, removing ruby dependency 
     155 - Fix for CYGWIN builds on ipv6 
     156 - Major refactor for extconf.rb 
     157 - Working mingw builds 
     158 - extconf optionally uses pkg_config over manual configuration 
     159 - extconf builds for 1.9 on any system that has 1.9 
     160 - extconf no longer links pthread explicitly 
     161 - looks for kqueue on all *nix systems 
     162 - better error output on std::runtime_error, now says where it came from 
     163 - Fixed some tests on jruby 
     164 - Added test for general send_data flaw, required for a bugfix in jruby build 
     165 - Added timeout to epoll tests 
     166 - Added fixes for java reactor ruby api 
     167 - Small addition of some docs in httpclient.rb and httpcli2.rb 
     168 - Some refactor and fixes in smtpserver.rb 
     169 - Added parenthesis where possible to avoid excess ruby warnings 
     170 - Refactor of $eventmachine_library logic for accuracy and maintenance, jruby 
     171 - EM::start_server now supports unix sockets 
     172 - EM::connect now supports unix sockets 
     173 - EM::defer @threadqueue now handled more gracefully 
     174 - Added better messages on exceptions raised 
     175 - Fix edge case in timer fires 
     176 - Explicitly require buftok.rb 
     177 - Add protocols to autoload, rather than require them all immediately 
     178 - Fix a bug in pr_eventmachine for outbound_q 
     179 - Refactors to take some of the use of defer out of tests. 
     180 - Fixes in EM.defer under start/stop conditions. Reduced scope of threads. 
  • trunk/ext

    • Property svn:ignore set to

      Makefile
      *.log
      *.o
      *.so
      *.dll
      *.bundle
  • trunk/ext/cmain.cpp

    r785 r788  
    33$Id$ 
    44 
    5 File:     cmain.cpp 
    6 Date:     06Apr06 
     5File:                  cmain.cpp 
     6Date:                  06Apr06 
    77 
    88Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. 
     
    2525static int bUseKqueue = 0; 
    2626 
     27extern "C" void ensure_eventmachine (const char *caller = "unknown caller") 
     28{ 
     29        if (!EventMachine) { 
     30                int err_size = 128; 
     31                char err_string[err_size]; 
     32                snprintf (err_string, err_size, "eventmachine not initialized: %s", caller); 
     33                throw std::runtime_error (err_string); 
     34        } 
     35} 
    2736 
    2837/*********************** 
     
    3645        //InstallSignalHandlers(); 
    3746        if (EventMachine) 
    38                 throw std::runtime_error ("already initialized"); 
     47                throw std::runtime_error ("eventmachine already initialized: evma_initialize_library"); 
    3948        EventMachine = new EventMachine_t (cb); 
    4049        if (bUseEpoll) 
     
    5160extern "C" void evma_release_library() 
    5261{ 
    53         if (!EventMachine) 
    54                 throw std::runtime_error ("not initialized"); 
     62        ensure_eventmachine("evma_release_library"); 
    5563        delete EventMachine; 
    5664        EventMachine = NULL; 
     
    6472extern "C" void evma_run_machine() 
    6573{ 
    66         if (!EventMachine) 
    67                 throw std::runtime_error ("not initialized"); 
     74        ensure_eventmachine("evma_run_machine"); 
    6875        EventMachine->Run(); 
    6976} 
     
    7683extern "C" const char *evma_install_oneshot_timer (int seconds) 
    7784{ 
    78         if (!EventMachine) 
    79                 throw std::runtime_error ("not initialized"); 
     85        ensure_eventmachine("evma_install_oneshot_timer"); 
    8086        return EventMachine->InstallOneshotTimer (seconds); 
    8187} 
     
    8894extern "C" const char *evma_connect_to_server (const char *server, int port) 
    8995{ 
    90         if (!EventMachine) 
    91                 throw std::runtime_error ("not initialized"); 
     96        ensure_eventmachine("evma_connect_to_server"); 
    9297        return EventMachine->ConnectToServer (server, port); 
    9398} 
     
    99104extern "C" const char *evma_connect_to_unix_server (const char *server) 
    100105{ 
    101         if (!EventMachine) 
    102                 throw std::runtime_error ("not initialized"); 
     106        ensure_eventmachine("evma_connect_to_unix_server"); 
    103107        return EventMachine->ConnectToUnixServer (server); 
    104108} 
     
    137141extern "C" const char *evma_create_tcp_server (const char *address, int port) 
    138142{ 
    139         if (!EventMachine) 
    140                 throw std::runtime_error ("not initialized"); 
     143        ensure_eventmachine("evma_create_tcp_server"); 
    141144        return EventMachine->CreateTcpServer (address, port); 
    142145} 
     
    148151extern "C" const char *evma_create_unix_domain_server (const char *filename) 
    149152{ 
    150         if (!EventMachine) 
    151                 throw std::runtime_error ("not initialized"); 
     153        ensure_eventmachine("evma_create_unix_domain_server"); 
    152154        return EventMachine->CreateUnixDomainServer (filename); 
    153155} 
     
    159161extern "C" const char *evma_open_datagram_socket (const char *address, int port) 
    160162{ 
    161         if (!EventMachine) 
    162                 throw std::runtime_error ("not initialized"); 
     163        ensure_eventmachine("evma_open_datagram_socket"); 
    163164        return EventMachine->OpenDatagramSocket (address, port); 
    164165} 
     
    170171extern "C" const char *evma_open_keyboard() 
    171172{ 
    172         if (!EventMachine) 
    173                 throw std::runtime_error ("not initialized"); 
     173        ensure_eventmachine("evma_open_keyboard"); 
    174174        return EventMachine->OpenKeyboard(); 
    175175} 
     
    183183extern "C" int evma_send_data_to_connection (const char *binding, const char *data, int data_length) 
    184184{ 
    185         if (!EventMachine) 
    186                 throw std::runtime_error ("not initialized"); 
     185        ensure_eventmachine("evma_send_data_to_connection"); 
    187186        return ConnectionDescriptor::SendDataToConnection (binding, data, data_length); 
    188187} 
     
    194193extern "C" int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port) 
    195194{ 
    196   if (!EventMachine) 
    197                 throw std::runtime_error ("not initialized"); 
     195        ensure_eventmachine("evma_send_datagram"); 
    198196        return DatagramDescriptor::SendDatagram (binding, data, data_length, address, port); 
    199197} 
     
    206204extern "C" void evma_close_connection (const char *binding, int after_writing) 
    207205{ 
    208         if (!EventMachine) 
    209                 throw std::runtime_error ("not initialized"); 
     206        ensure_eventmachine("evma_close_connection"); 
    210207        ConnectionDescriptor::CloseConnection (binding, (after_writing ? true : false)); 
    211208} 
     
    217214extern "C" int evma_report_connection_error_status (const char *binding) 
    218215{ 
    219         if (!EventMachine) 
    220                 throw std::runtime_error ("not initialized"); 
     216        ensure_eventmachine("evma_report_connection_error_status"); 
    221217        return ConnectionDescriptor::ReportErrorStatus (binding); 
    222218} 
     
    228224extern "C" void evma_stop_tcp_server (const char *binding) 
    229225{ 
    230         if (!EventMachine) 
    231                 throw std::runtime_error ("not initialized"); 
     226        ensure_eventmachine("evma_stop_tcp_server"); 
    232227        AcceptorDescriptor::StopAcceptor (binding); 
    233228} 
     
    240235extern "C" void evma_stop_machine() 
    241236{ 
    242         if (!EventMachine) 
    243                 throw std::runtime_error ("not initialized"); 
     237        ensure_eventmachine("evma_stop_machine"); 
    244238        EventMachine->ScheduleHalt(); 
    245239} 
     
    252246extern "C" void evma_start_tls (const char *binding) 
    253247{ 
    254         if (!EventMachine) 
    255                 throw std::runtime_error ("not initialized"); 
     248        ensure_eventmachine("evma_start_tls"); 
    256249        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    257250        if (ed) 
     
    265258extern "C" void evma_set_tls_parms (const char *binding, const char *privatekey_filename, const char *certchain_filename) 
    266259{ 
    267         if (!EventMachine) 
    268                 throw std::runtime_error ("not initialized"); 
     260        ensure_eventmachine("evma_set_tls_parms"); 
    269261        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    270262        if (ed) 
     
    279271extern "C" int evma_get_peername (const char *binding, struct sockaddr *sa) 
    280272{ 
    281         if (!EventMachine) 
    282                 throw std::runtime_error ("not initialized"); 
     273        ensure_eventmachine("evma_get_peername"); 
    283274        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    284275        if (ed) { 
     
    295286extern "C" int evma_get_sockname (const char *binding, struct sockaddr *sa) 
    296287{ 
    297         if (!EventMachine) 
    298                 throw std::runtime_error ("not initialized"); 
     288        ensure_eventmachine("evma_get_sockname"); 
    299289        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    300290        if (ed) { 
     
    311301extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid) 
    312302{ 
    313         if (!EventMachine) 
    314                 throw std::runtime_error ("not initialized"); 
     303        ensure_eventmachine("evma_get_subprocess_pid"); 
    315304        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    316305        if (ed) { 
     
    327316extern "C" int evma_get_subprocess_status (const char *binding, int *status) 
    328317{ 
    329         if (!EventMachine) 
    330                 throw std::runtime_error ("not initialized"); 
     318        ensure_eventmachine("evma_get_subprocess_status"); 
    331319        if (status) { 
    332320                *status = EventMachine->SubprocessExitStatus; 
     
    344332extern "C" void evma_signal_loopbreak() 
    345333{ 
    346         if (!EventMachine) 
    347                 throw std::runtime_error ("not initialized"); 
     334        ensure_eventmachine("evma_signal_loopbreak"); 
    348335        EventMachine->SignalLoopBreaker(); 
    349336} 
     
    357344extern "C" const char *evma__write_file (const char *filename) 
    358345{ 
    359         if (!EventMachine) 
    360                 throw std::runtime_error ("not initialized"); 
     346        ensure_eventmachine("evma__write_file"); 
    361347        return EventMachine->_OpenFileForWriting (filename); 
    362348} 
     
    369355extern "C" int evma_get_comm_inactivity_timeout (const char *binding, int *value) 
    370356{ 
    371         if (!EventMachine) 
    372                 throw std::runtime_error ("not initialized"); 
     357        ensure_eventmachine("evma_get_comm_inactivity_timeout"); 
    373358        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    374359        if (ed) { 
     
    385370extern "C" int evma_set_comm_inactivity_timeout (const char *binding, int *value) 
    386371{ 
    387         if (!EventMachine) 
    388                 throw std::runtime_error ("not initialized"); 
     372        ensure_eventmachine("evma_set_comm_inactivity_timeout"); 
    389373        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    390374        if (ed) { 
     
    402386extern "C" void evma_set_timer_quantum (int interval) 
    403387{ 
    404         if (!EventMachine) 
    405                 throw std::runtime_error ("not initialized"); 
     388        ensure_eventmachine("evma_set_timer_quantum"); 
    406389        EventMachine->SetTimerQuantum (interval); 
    407390} 
     
    415398        // This may only be called if the reactor is not running. 
    416399        if (EventMachine) 
    417                 throw std::runtime_error ("already initialized"); 
     400                throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count"); 
    418401        EventMachine_t::SetMaxTimerCount (ct); 
    419402} 
     
    425408extern "C" void evma_setuid_string (const char *username) 
    426409{ 
    427     // We do NOT need to be running an EM instance because this method is static. 
    428     EventMachine_t::SetuidString (username); 
     410       // We do NOT need to be running an EM instance because this method is static. 
     411       EventMachine_t::SetuidString (username); 
    429412} 
    430413 
     
    436419extern "C" const char *evma_popen (char * const*cmd_strings) 
    437420{ 
    438         if (!EventMachine) 
    439                 throw std::runtime_error ("not initialized"); 
     421        ensure_eventmachine("evma_popen"); 
    440422        return EventMachine->Socketpair (cmd_strings); 
    441423} 
     
    448430extern "C" int evma_get_outbound_data_size (const char *binding) 
    449431{ 
    450         if (!EventMachine) 
    451                 throw std::runtime_error ("not initialized"); 
     432        ensure_eventmachine("evma_get_outbound_data_size"); 
    452433        EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    453434        return ed ? ed->GetOutboundDataSize() : 0; 
     
    510491        int r; 
    511492 
    512         if (!EventMachine) 
    513                 throw std::runtime_error("not initialized"); 
     493        ensure_eventmachine("evma_send_file_data_to_connection"); 
    514494 
    515495        int Fd = open (filename, O_RDONLY); 
     
    549529} 
    550530 
    551  
    552  
    553  
  • trunk/ext/em.cpp

    r785 r788  
    632632 
    633633 
     634#ifdef BUILD_FOR_RUBY 
    634635/***************** 
    635636_SelectDataSelect 
     
    660661        #endif 
    661662} 
     663#endif 
    662664 
    663665 
     
    12851287 
    12861288        static struct sockaddr_in in4; 
     1289        #ifndef __CYGWIN__ 
    12871290        static struct sockaddr_in6 in6; 
     1291        #endif 
    12881292        struct hostent *hp; 
    12891293 
     
    13021306        } 
    13031307 
    1304         #ifdef OS_UNIX 
     1308        #if defined(OS_UNIX) && !defined(__CYGWIN__) 
    13051309        memset (&in6, 0, sizeof(in6)); 
    13061310        if (inet_pton (AF_INET6, server, in6.sin6_addr.s6_addr) > 0) { 
  • trunk/ext/extconf.rb

    r677 r788  
    55# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. 
    66# Gmail: blackhedd 
    7 #  
     7# 
    88# This program is free software; you can redistribute it and/or modify 
    99# it under the terms of either: 1) the GNU General Public License 
    1010# as published by the Free Software Foundation; either version 2 of the 
    1111# License, or (at your option) any later version; or 2) Ruby's License. 
    12 #  
     12# 
    1313# See the file COPYING for complete licensing information. 
    1414# 
     
    1919# 
    2020 
     21def check_libs libs = [], fatal = false 
     22  libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) } 
     23end 
     24 
     25def check_heads heads = [], fatal = false 
     26  heads.all? { |head| have_header(head) || (abort("could not find header: #{head}") if fatal)} 
     27end 
     28 
     29def add_define(name) 
     30  $defs.push("-D#{name}") 
     31end 
     32 
    2133require 'mkmf' 
    2234 
    23 flags = [] 
     35add_define 'BUILD_FOR_RUBY' 
    2436 
    25 case RUBY_PLATFORM.split('-',2)[1] 
    26 when 'mswin32', 'mingw32', 'bccwin32' 
    27   unless have_header('windows.h') and 
    28       have_header('winsock.h') and 
    29       have_library('kernel32') and 
    30       have_library('rpcrt4') and 
    31       have_library('gdi32') 
    32     exit 
    33   end 
     37add_define "HAVE_TBR" if have_func('rb_thread_blocking_region') and have_macro('RB_UBF_DFL', 'ruby.h') 
    3438 
    35   flags << "-D OS_WIN32" 
    36   flags << '-D BUILD_FOR_RUBY' 
    37   flags << "-EHs" 
    38   flags << "-GR" 
     39# Minor platform details between *nix and Windows: 
    3940 
    40   dir_config('ssl') 
    41   if have_library('ssleay32') and 
    42           have_library('libeay32') and 
    43           have_header('openssl/ssl.h') and 
    44           have_header('openssl/err.h') 
    45     flags << '-D WITH_SSL' 
     41if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/ 
     42  GNU_CHAIN = $1 == 'mingw' 
     43  OS_WIN32 = true 
     44  add_define "OS_WIN32" 
     45else 
     46  GNU_CHAIN = true 
     47  OS_UNIX = true 
     48  add_define 'OS_UNIX' 
     49 
     50  add_define "HAVE_KQUEUE" if have_header("sys/event.h") and have_header("sys/queue.h") 
     51 
     52  # check_libs(%w[pthread], true) 
     53end 
     54 
     55# Main platform invariances: 
     56 
     57case RUBY_PLATFORM 
     58when /mswin32/, /mingw32/, /bccwin32/ 
     59  check_heads(%w[windows.h winsock.h], true) 
     60  check_libs(%w[kernel32 rpcrt4 gdi32], true) 
     61 
     62  if GNU_CHAIN 
     63    CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++" 
    4664  else 
    47     flags << '-D WITHOUT_SSL' 
     65    $defs.push "-EHs" 
     66    $defs.push "-GR" 
    4867  end 
    4968 
    5069when /solaris/ 
    51   unless have_library('pthread') and 
    52         have_library('nsl') and 
    53         have_library('socket') 
    54           exit 
    55   end 
     70  check_libs(%w[nsl socket], true) 
    5671 
    57   flags << '-D OS_UNIX' 
    58   flags << '-D OS_SOLARIS8' 
    59   flags << '-D BUILD_FOR_RUBY' 
    60  
    61   dir_config('ssl') 
    62   if have_library('ssl') and 
    63           have_library('crypto') and 
    64           have_header('openssl/ssl.h') and 
    65           have_header('openssl/err.h') 
    66     flags << '-D WITH_SSL' 
    67   else 
    68     flags << '-D WITHOUT_SSL' 
    69   end 
     72  add_define 'OS_SOLARIS8' 
    7073 
    7174  # on Unix we need a g++ link, not gcc. 
     
    7881  end 
    7982 
    80 when /openbsd/   
     83when /openbsd/ 
    8184  # OpenBSD branch contributed by Guillaume Sellier. 
    82   flags << '-DOS_UNIX' 
    83   flags << '-DBUILD_FOR_RUBY' 
    84     
    85   dir_config('ssl') # here I don't know why we have to check -lcrypto before -lssl otherwise -lssl is not found 
    86   if have_library('crypto') and 
    87         have_library('ssl') and 
    88         have_header('openssl/ssl.h') and 
    89         have_header('openssl/err.h') 
    90     flags << '-DWITH_SSL' 
    91   else 
    92     flags << '-DWITHOUT_SSL' 
    93   end 
     85 
    9486  # on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs 
    9587  CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++" 
    9688 
     89when /darwin/ 
    9790 
    98 when /darwin/ 
    99   flags << '-DOS_UNIX' 
    100   flags << '-DBUILD_FOR_RUBY' 
    101  
    102   if have_header("sys/event.h") and have_header("sys/queue.h") 
    103     flags << "-DHAVE_KQUEUE" 
    104   end 
    105  
    106   dir_config('ssl') 
    107   if have_library('ssl') and 
    108           have_library('crypto') and 
    109           have_library('C') and 
    110           have_header('openssl/ssl.h') and 
    111           have_header('openssl/err.h') 
    112     flags << '-DWITH_SSL' 
    113   else 
    114     flags << '-DWITHOUT_SSL' 
    115   end 
    11691  # on Unix we need a g++ link, not gcc. 
    11792  # Ff line contributed by Daniel Harple. 
     
    11994 
    12095when /linux/ 
    121   unless have_library('pthread') 
    122           exit 
    123   end 
    124  
    125   flags << '-DOS_UNIX' 
    126   flags << '-DBUILD_FOR_RUBY' 
    12796 
    12897  # Original epoll test is inadequate because 2.4 kernels have the header 
    12998  # but not the code. 
    130   #flags << '-DHAVE_EPOLL' if have_header('sys/epoll.h') 
     99  # add_define 'HAVE_EPOLL' if have_header('sys/epoll.h') 
    131100  if have_header('sys/epoll.h') 
    132          File.open("hasEpollTest.c", "w") {|f| 
    133                  f.puts "#include <sys/epoll.h>" 
    134                  f.puts "int main() { epoll_create(1024); return 0;}" 
    135          } 
    136          (e = system( "gcc hasEpollTest.c -o hasEpollTest " )) and (e = $?.to_i) 
    137          `rm -f hasEpollTest.c hasEpollTest` 
    138          flags << '-DHAVE_EPOLL' if e == 0 
     101    File.open("hasEpollTest.c", "w") {|f| 
     102      f.puts "#include <sys/epoll.h>" 
     103      f.puts "int main() { epoll_create(1024); return 0;}" 
     104    } 
     105    (e = system( "gcc hasEpollTest.c -o hasEpollTest " )) and (e = $?.to_i) 
     106    `rm -f hasEpollTest.c hasEpollTest` 
     107    add_define 'HAVE_EPOLL' if e == 0 
    139108  end 
    140109 
    141   if have_func('rb_thread_blocking_region') and have_macro('RB_UBF_DFL', 'ruby.h') 
    142           flags << "-DHAVE_TBR" 
    143   end 
    144  
    145   dir_config('ssl', "#{ENV['OPENSSL']}/include", ENV['OPENSSL']) 
    146   # Check for libcrypto twice, before and after ssl. That's because on some platforms 
    147   # and openssl versions, libssl will emit unresolved externals from crypto. It 
    148   # would be cleaner to simply check crypto first, but that doesn't always work in  
    149   # Ruby. The order we check them doesn't seem to control the order in which they're 
    150   # emitted into the link command. This is pretty weird, I have to admit. 
    151   if have_library('crypto') and 
    152           have_library('ssl') and 
    153           have_library('crypto') and 
    154           have_header('openssl/ssl.h') and 
    155           have_header('openssl/err.h') 
    156     flags << '-DWITH_SSL' 
    157   else 
    158     flags << '-DWITHOUT_SSL' 
    159   end 
    160110  # on Unix we need a g++ link, not gcc. 
    161111  CONFIG['LDSHARED'] = "$(CXX) -shared" 
    162  
    163   # Modify the mkmf constant LINK_SO so the generated shared object is stripped. 
    164   # You might think modifying CONFIG['LINK_SO'] would be a better way to do this, 
    165   # but it doesn't work because mkmf doesn't look at CONFIG['LINK_SO'] again after 
    166   # it initializes. 
    167   linkso = Object.send :remove_const, "LINK_SO" 
    168   LINK_SO = linkso + "; strip $@" 
    169  
    170112else 
    171   unless have_library('pthread') 
    172           exit 
    173   end 
    174  
    175   flags << '-DOS_UNIX' 
    176   flags << '-DBUILD_FOR_RUBY' 
    177  
    178   if have_header("sys/event.h") and have_header("sys/queue.h") 
    179     flags << "-DHAVE_KQUEUE" 
    180   end 
    181  
    182   dir_config('ssl') 
    183   if have_library('ssl') and 
    184           have_library('crypto') and 
    185           have_header('openssl/ssl.h') and 
    186           have_header('openssl/err.h') 
    187     flags << '-DWITH_SSL' 
    188   else 
    189     flags << '-DWITHOUT_SSL' 
    190   end 
    191113  # on Unix we need a g++ link, not gcc. 
    192114  CONFIG['LDSHARED'] = "$(CXX) -shared" 
    193  
    194115end 
    195116 
    196 if $CPPFLAGS 
    197   $CPPFLAGS += ' ' + flags.join(' ') 
    198 else 
    199   $CFLAGS += ' ' + flags.join(' ') 
     117# OpenSSL: 
     118 
     119def manual_ssl_config 
     120  ssl_libs_heads_args = { 
     121    :unix => [%w[ssl crypto], %w[openssl/ssl.h openssl/err.h]], 
     122    :darwin => [%w[ssl crypto C], %w[openssl/ssl.h openssl/err.h]], 
     123    # openbsd and linux: 
     124    :crypto_hack => [%w[crypto ssl crypto], %w[openssl/ssl.h openssl/err.h]], 
     125    :mswin => [%w[ssleay32 libeay32], %w[openssl/ssl.h openssl/err.h]], 
     126  } 
     127 
     128  dc_flags = ['ssl'] 
     129  dc_flags += ["#{ENV['OPENSSL']}/include", ENV['OPENSSL']] if /linux/ =~ RUBY_PLATFORM 
     130 
     131  libs, heads = case RUBY_PLATFORM 
     132  when /mswin/    ; ssl_libs_heads_args[:mswin] 
     133  when /mingw/    ; ssl_libs_heads_args[:unix] 
     134  when /darwin/   ; ssl_libs_heads_args[:darwin] 
     135  when /openbsd/  ; ssl_libs_heads_args[:crypto_hack] 
     136  when /linux/    ; ssl_libs_heads_args[:crypto_hack] 
     137  else              ssl_libs_heads_args[:unix] 
     138  end 
     139  dir_config(*dc_flags) 
     140  check_libs(libs) and check_heads(heads) 
    200141end 
    201142 
     143# Try to use pkg_config first, fixes #73 
     144if pkg_config('openssl') || manual_ssl_config 
     145  add_define "WITH_SSL" 
     146else 
     147  add_define "WITHOUT_SSL" 
     148end 
    202149 
    203150create_makefile "rubyeventmachine" 
  • trunk/java/src/com/rubyeventmachine

    • Property svn:ignore set to
      *.class
  • trunk/java/src/com/rubyeventmachine/DefaultConnectionFactory.java

    r668 r788  
    4040         * useful for unit testing. 
    4141         */ 
    42         @Override 
    4342        public Connection connection() { 
    4443                return new Connection(); 
  • trunk/lib

    • Property svn:ignore set to
      *.jar
      *.bundle
      *.dll
      *.so
  • trunk/lib/eventmachine.rb

    r785 r788  
    4242# 
    4343 
    44 =begin 
    45 $eventmachine_library ||= nil 
     44 
     45unless defined?($eventmachine_library) 
     46  $eventmachine_library = ENV['EVENTMACHINE_LIBRARY'] || :cascade 
     47end 
     48$eventmachine_library = $eventmachine_library.to_sym 
     49 
    4650case $eventmachine_library 
    4751when :pure_ruby 
     
    4953when :extension 
    5054  require 'rubyeventmachine' 
    51 else 
     55when :java 
     56  require 'jeventmachine' 
     57else # :cascade 
    5258  # This is the case that most user code will take. 
    5359  # Prefer the extension if available. 
    5460  begin 
    55     require 'rubyeventmachine' 
     61    if RUBY_PLATFORM =~ /java/ 
     62      require 'java' 
     63      require 'jeventmachine' 
     64      $eventmachine_library = :java 
     65    else 
     66      require 'rubyeventmachine' 
     67      $eventmachine_library = :extension 
     68    end 
    5669  rescue LoadError 
     70    warn "# EventMachine fell back to pure ruby mode" if $DEBUG 
    5771    require 'pr_eventmachine' 
     72    $eventmachine_library = :pure_ruby 
    5873  end 
    5974end 
    60 =end 
    61  
    62  
    63 if RUBY_PLATFORM =~ /java/ 
    64         require 'java' 
    65         require 'jeventmachine' 
    66 else 
    67         if $eventmachine_library == :pure_ruby or ENV['EVENTMACHINE_LIBRARY'] == "pure_ruby" 
    68                 require 'pr_eventmachine' 
    69         else 
    70                 require 'rubyeventmachine' 
    71         end 
    72 end 
    73  
    7475 
    7576require "eventmachine_version" 
     
    172173#  
    173174module EventMachine 
     175  class << self 
     176    attr_reader :threadpool 
     177  end 
    174178 
    175179 
     
    231235                                run_machine 
    232236                        ensure 
    233                                 release_machine 
     237                          begin 
     238                                  release_machine 
     239                          ensure 
     240                                if @threadpool 
     241                                  @threadpool.each { |t| t.exit } 
     242                                  @threadpool.each { |t| t.kill! if t.alive? } 
     243                                  @threadqueue = nil 
     244                                  @resultqueue = nil                               
     245                          end 
     246                                @threadpool = nil 
     247                                end 
    234248                                @reactor_running = false 
    235249                        end 
     
    516530  #   
    517531  # 
    518   def EventMachine::start_server server, port, handler=nil, *args, &block 
     532  def EventMachine::start_server server, port=nil, handler=nil, *args, &block 
     533     
     534    begin 
     535      port = Integer(port) 
     536    rescue ArgumentError, TypeError 
     537      args.unshift handler if handler 
     538      handler = port 
     539      port = nil 
     540    end if port 
     541     
    519542    klass = if (handler and handler.is_a?(Class)) 
    520543      handler 
     
    529552    end 
    530553 
    531     s = start_tcp_server server, port 
     554    s = if port 
     555          start_tcp_server server, port 
     556        else 
     557          start_unix_server server 
     558        end 
    532559    @acceptors[s] = [klass,args,block] 
    533560    s 
     
    544571  end 
    545572 
    546   def EventMachine::start_unix_domain_server filename, handler=nil, *args, &block 
    547     klass = if (handler and handler.is_a?(Class)) 
    548       handler 
    549     else 
    550       Class.new( Connection ) {handler and include handler} 
    551     end 
    552  
    553     arity = klass.instance_method(:initialize).arity 
    554     expected = arity >= 0 ? arity : -(arity + 1) 
    555     if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected) 
    556       raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})"  
    557     end 
    558  
    559     s = start_unix_server filename 
    560     @acceptors[s] = [klass,args,block] 
    561     s 
     573  def EventMachine::start_unix_domain_server filename, *args, &block 
     574    start_server filename, *args, &block 
    562575  end 
    563576 
     
    659672  # if at all possible. 
    660673  # 
    661   def EventMachine::connect server, port, handler=nil, *args 
     674  def EventMachine::connect server, port=nil, handler=nil, *args 
     675    begin 
     676      port = Integer(port) 
     677    rescue ArgumentError, TypeError 
     678      args.unshift handler if handler 
     679      handler = port 
     680      port = nil 
     681    end if port 
     682 
    662683    klass = if (handler and handler.is_a?(Class)) 
    663684      handler 
     
    672693    end 
    673694 
    674     s = connect_server server, port 
     695    s = if port 
     696          connect_server server, port 
     697        else 
     698          connect_unix_server server 
     699        end 
     700 
    675701    c = klass.new s, *args 
    676702    @conns[s] = c 
     
    784810        # Eventually this has to get properly documented and unified with the TCP-connect methods. 
    785811        # Note how nearly identical this is to EventMachine#connect 
    786         def EventMachine::connect_unix_domain socketname, handler=nil, *args 
    787                 klass = if (handler and handler.is_a?(Class)) 
    788                         handler 
    789                 else 
    790                         Class.new( Connection ) {handler and include handler} 
    791                 end 
    792  
    793     arity = klass.instance_method(:initialize).arity 
    794     expected = arity >= 0 ? arity : -(arity + 1) 
    795     if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected) 
    796       raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})" 
    797     end 
    798  
    799                 s = connect_unix_server socketname 
    800                 c = klass.new s, *args 
    801                 @conns[s] = c 
    802                 block_given? and yield c 
    803                 c 
     812        def EventMachine::connect_unix_domain socketname, *args, &blk 
     813          connect socketname, *args, &blk 
    804814        end 
    805815 
     
    9941004        # has no constructor. 
    9951005        # 
    996         def self::defer op, callback = nil 
    997                 @need_threadqueue ||= 0 
    998                 if @need_threadqueue == 0 
    999                         @need_threadqueue = 1 
     1006        def self::defer op = nil, callback = nil, &blk 
     1007                unless @threadpool 
    10001008                        require 'thread' 
     1009                        @threadpool = [] 
    10011010                        @threadqueue = Queue.new 
    10021011                        @resultqueue = Queue.new 
    1003                         20.times {|ix| 
    1004                                 Thread.new { 
    1005                                         my_ix = ix 
    1006                                         loop { 
    1007                                                 op,cback = @threadqueue.pop 
    1008                                                 result = op.call 
    1009                                                 @resultqueue << [result, cback] 
    1010                                                 EventMachine.signal_loopbreak 
    1011                                         } 
    1012                                 } 
    1013                         } 
    1014                 end 
    1015  
    1016                 @threadqueue << [op,callback] 
     1012                        spawn_threadpool 
     1013                end 
     1014 
     1015                @threadqueue << [op||blk,callback] 
     1016        end 
     1017         
     1018        def self.spawn_threadpool 
     1019          until @threadpool.size == 20 
     1020                        thread = Thread.new do 
     1021                                while true 
     1022                                        op, cback = *@threadqueue.pop 
     1023                                        result = op.call 
     1024                                        @resultqueue << [result, cback] 
     1025                                        EventMachine.signal_loopbreak 
     1026                                end 
     1027                        end 
     1028                        @threadpool << thread 
     1029                end 
    10171030        end 
    10181031 
     
    11651178                # 
    11661179                if opcode == ConnectionData 
    1167                         c = @conns[conn_binding] or raise ConnectionNotBound 
     1180                        c = @conns[conn_binding] or raise ConnectionNotBound, "received data #{data} for unknown signature: #{conn_binding}" 
    11681181                        c.receive_data data 
    11691182                elsif opcode == ConnectionUnbound 
     
    11781191                                # no-op 
    11791192                        else 
    1180                                 raise ConnectionNotBound 
     1193                                raise ConnectionNotBound, "recieved ConnectionUnbound for an unknown signature: #{conn_binding}" 
    11811194                        end 
    11821195                elsif opcode == ConnectionAccepted 
     
    11881201                        c # (needed?) 
    11891202                elsif opcode == TimerFired 
    1190                         t = @timers.delete( data ) or raise UnknownTimerFired 
     1203                        t = @timers.delete( data ) or raise UnknownTimerFired, "timer data: #{data}" 
    11911204                        t.call 
    11921205                elsif opcode == ConnectionCompleted 
    1193                         c = @conns[conn_binding] or raise ConnectionNotBound 
     1206                        c = @conns[conn_binding] or raise ConnectionNotBound, "received ConnectionCompleted for unknown signature: #{conn_binding}" 
    11941207                        c.connection_completed 
    11951208                elsif opcode == LoopbreakSignalled 
     
    13491362  # connection-specific arguments 
    13501363  # 
    1351   def self.new sig, *args #:nodoc: 
     1364  def self.new(sig, *args) #:nodoc: 
    13521365    allocate.instance_eval do 
    13531366      # Call a superclass's #initialize if it has one 
    1354       initialize *args 
     1367      initialize(*args) 
    13551368 
    13561369      # Store signature and run #post_init 
     
    16861699                end 
    16871700                def fire 
    1688                         @code.call 
    1689                         schedule unless @cancelled 
     1701                        unless @cancelled 
     1702                                @code.call 
     1703                                schedule 
     1704                        end 
    16901705                end 
    16911706                def cancel 
     
    17061721        end 
    17071722 
    1708  
    1709  
    1710  
    17111723end 
     1724 
     1725# Is inside of protocols/ but not in the namespace? 
     1726require 'protocols/buftok' 
    17121727 
    17131728module Protocols 
    17141729        # In this module, we define standard protocol implementations. 
    17151730        # They get included from separate source files. 
     1731         
     1732        # TODO / XXX: We're munging the LOAD_PATH! 
     1733        # A good citizen would use eventmachine/protocols/tcptest. 
     1734        # TODO : various autotools are completely useless with the lack of naming 
     1735        # convention, we need to correct that! 
     1736        autoload :TcpConnectTester, 'protocols/tcptest' 
     1737        autoload :HttpClient, 'protocols/httpclient' 
     1738        autoload :LineAndTextProtocol, 'protocols/line_and_text' 
     1739        autoload :HeaderAndContentProtocol, 'protocols/header_and_content' 
     1740        autoload :LineText2, 'protocols/linetext2' 
     1741        autoload :HttpClient2, 'protocols/httpcli2' 
     1742        autoload :Stomp, 'protocols/stomp' 
     1743        autoload :SmtpClient, 'protocols/smtpclient' 
     1744        autoload :SmtpServer, 'protocols/smtpserver' 
     1745        autoload :SASLauth, 'protocols/saslauth' 
     1746         
     1747        #require 'protocols/postgres' UNCOMMENT THIS LINE WHEN THE POSTGRES CODE IS READY FOR PRIME TIME. 
    17161748end 
    17171749 
    17181750end # module EventMachine 
    1719  
    1720  
    17211751 
    17221752# Save everyone some typing. 
     
    17241754EM::P = EventMachine::Protocols 
    17251755 
    1726  
    1727 # At the bottom of this module, we load up protocol handlers that depend on some 
    1728 # of the classes defined here. Eventually we should refactor this out so it's 
    1729 # laid out in a more logical way. 
    1730 # 
    1731  
    1732 require 'protocols/tcptest' 
    1733 require 'protocols/httpclient' 
    1734 require 'protocols/line_and_text' 
    1735 require 'protocols/linetext2' 
    1736 require 'protocols/header_and_content' 
    1737 require 'protocols/httpcli2' 
    1738 require 'protocols/stomp' 
    1739 require 'protocols/smtpclient' 
    1740 require 'protocols/smtpserver' 
    1741 require 'protocols/saslauth' 
    1742 #require 'protocols/postgres' UNCOMMENT THIS LINE WHEN THE POSTGRES CODE IS READY FOR PRIME TIME. 
    1743  
    17441756require 'em/processes' 
    1745  
    1746  
  • trunk/lib/jeventmachine.rb

    r771 r788  
    2929# which is a garden-variety Ruby-extension glue module. 
    3030 
    31  
     31require 'java' 
    3232require 'em_reactor' 
    3333 
     
    4848                        s = String.from_java_bytes(a3.array[a3.position...a3.limit]) 
    4949                        EventMachine::event_callback a1, a2, s 
     50                end 
     51        end 
     52        class Connection < com.rubyeventmachine.Connection 
     53                def associate_callback_target sig 
     54                        # No-op for the time being. 
    5055                end 
    5156        end 
  • trunk/lib/pr_eventmachine.rb

    r668 r788  
    579579 
    580580          if w < data.length 
    581             $outbound_q.unshift data[w..-1] 
     581            @outbound_q.unshift data[w..-1] 
    582582            break 
    583583          end 
  • trunk/lib/protocols/httpcli2.rb

    r668 r788  
    2929module Protocols 
    3030 
    31  
     31  # = Example 
     32  # 
     33  #   
     34  #  EM.run{ 
     35  #    include EM::Protocols 
     36  #    conn = HttpClient2.connect 'google.com', 80 
     37  #   
     38  #    req = conn.get('/') 
     39  #    req.callback{ 
     40  #      p(req.content) 
     41  #    } 
    3242        class HttpClient2 < Connection 
    3343                include LineText2 
  • trunk/lib/protocols/httpclient.rb

    r786 r788  
    6565  # Refactor this code so that protocol errors all get handled one way (an exception?), 
    6666  # instead of sprinkling set_deferred_status :failed calls everywhere. 
     67 
     68  # === Arg list 
     69  # :host => 'ip/dns', :port => fixnum, :verb => 'GET', :request => 'path',  
     70  # :basic_auth => {:username => '', :password => ''}, :content => 'content', 
     71  # :contenttype => 'text/plain', :query_string => '', :host_header => '', 
     72  # :cookie => '' 
    6773 
    6874  def self.request( args = {} ) 
  • trunk/lib/protocols/smtpserver.rb

    r668 r788  
    120120                def receive_line ln 
    121121                        @@parms[:verbose] and $>.puts ">>> #{ln}" 
    122                         if @state.include?(:data) 
    123                                 process_data_line ln 
    124                         elsif ln =~ EhloRegex 
     122                         
     123                        return process_data_line ln if @state.include?(:data) 
     124                         
     125                        case ln 
     126                        when EhloRegex 
    125127                                process_ehlo $'.dup 
    126                         elsif ln =~ HeloRegex 
     128                        when HeloRegex 
    127129                                process_helo $'.dup 
    128                         elsif ln =~ MailFromRegex 
     130                        when MailFromRegex 
    129131                                process_mail_from $'.dup 
    130                         elsif ln =~ RcptToRegex 
     132                        when RcptToRegex 
    131133                                process_rcpt_to $'.dup 
    132                         elsif ln =~ DataRegex 
     134                        when DataRegex 
    133135                                process_data 
    134                         elsif ln =~ RsetRegex 
     136                        when RsetRegex 
    135137                                process_rset 
    136                         elsif ln =~ VrfyRegex 
     138                        when VrfyRegex 
    137139                                process_vrfy 
    138                         elsif ln =~ ExpnRegex 
     140                        when ExpnRegex 
    139141                                process_expn 
    140                         elsif ln =~ HelpRegex 
     142                        when HelpRegex 
    141143                                process_help 
    142                         elsif ln =~ NoopRegex 
     144                        when NoopRegex 
    143145                                process_noop 
    144                         elsif ln =~ QuitRegex 
     146                        when QuitRegex 
    145147                                process_quit 
    146                         elsif ln =~ StarttlsRegex 
     148                        when StarttlsRegex 
    147149                                process_starttls 
    148                         elsif ln =~ AuthRegex 
     150                        when AuthRegex 
    149151                                process_auth $'.dup 
    150152                        else 
     
    153155                end 
    154156 
    155  
     157    # TODO - implement this properly, the implementation is a stub! 
     158    def process_vrfy 
     159      send_data "250 Ok, but unimplemented\r\n" 
     160    end 
     161    # TODO - implement this properly, the implementation is a stub! 
     162    def process_help 
     163      send_data "250 Ok, but unimplemented\r\n" 
     164    end 
     165    # TODO - implement this properly, the implementation is a stub! 
     166    def process_expn 
     167      send_data "250 Ok, but unimplemented\r\n" 
     168    end 
    156169 
    157170                #-- 
     
    290303 
    291304                                if d.respond_to?(:callback) 
    292                                         d.callback &succeeded 
    293                                         d.errback &failed 
     305                                        d.callback(&succeeded) 
     306                                        d.errback(&failed) 
    294307                                else 
    295308                                        (d ? succeeded : failed).call 
     
    384397 
    385398                                if d.respond_to?(:set_deferred_status) 
    386                                         d.callback &succeeded 
    387                                         d.errback &failed 
     399                                        d.callback(&succeeded) 
     400                                        d.errback(&failed) 
    388401                                else 
    389402                                        (d ? succeeded : failed).call 
     
    434447 
    435448                                if d.respond_to?(:set_deferred_status) 
    436                                         d.callback &succeeded 
    437                                         d.errback &failed 
     449                                        d.callback(&succeeded) 
     450                                        d.errback(&failed) 
    438451                                else 
    439452                                        (d ? succeeded : failed).call 
  • trunk/Rakefile

    r785 r788  
    1 #! /usr/bin/env rake 
     1#!/usr/bin/env rake 
    22#-- 
    33# Ruby/EventMachine 
     
    1313#++ 
    1414 
     15### OLD RAKE: ### 
     16# # The tasks and external gemspecs we used to generate binary gems are now 
     17# # obsolete. Use Patrick Hurley's gembuilder to build binary gems for any 
     18# # desired platform. 
     19# # To build a binary gem on Win32, ensure that the include and lib paths 
     20# # both contain the proper references to OPENSSL. Use the static version 
     21# # of the libraries, not the dynamic, otherwise we expose the user to a 
     22# # runtime dependency. 
     23#  
     24# # To build a binary gem for win32, first build rubyeventmachine.so 
     25# # using VC6 outside of the build tree (the normal way: ruby extconf.rb, 
     26# # and then nmake). Then copy rubyeventmachine.so into the lib directory, 
     27# # and run rake gemwin32. 
     28# 
    1529 
     30require 'rubygems'  unless defined?(Gem) 
     31require 'rake'      unless defined?(Rake) 
    1632require 'rake/gempackagetask' 
    17 require 'rake/clean' 
    1833 
     34Package = false # Build zips and tarballs? 
     35Dir.glob('tasks/*.rake').each { |r| Rake.application.add_import r } 
    1936 
    20 $can_minitar = false 
    21 begin 
    22   require 'archive/tar/minitar' 
    23   require 'zlib' 
    24   $can_minitar  = true 
    25 rescue LoadError 
     37# e.g. rake EVENTMACHINE_LIBRARY=java for forcing java build tasks as defaults! 
     38$eventmachine_library = :java if RUBY_PLATFORM =~ /java/ || ENV['EVENTMACHINE_LIBRARY'] == 'java' 
     39$eventmachine_library = :pure_ruby if ENV['EVENTMACHINE_LIBRARY'] == 'pure_ruby' 
     40 
     41# If running under rubygems... 
     42__DIR__ ||= File.expand_path(File.dirname(__FILE__)) 
     43if Gem.path.any? {|path| %r(^#{Regexp.escape path}) =~ __DIR__} 
     44  task :default => :gem_build 
     45else 
     46  desc "Run tests." 
     47  task :default => [:build, :test] 
    2648end 
    2749 
    28 $: << "lib" 
    29 require 'eventmachine_version' 
    30 $version = EventMachine::VERSION 
    31 $distdir  = "eventmachine-#$version" 
    32 $tardist  = "#$distdir.tar.gz" 
    33 $name = "eventmachine" 
     50desc ":default build when running under rubygems." 
     51task :gem_build => :build 
    3452 
    35  
    36 # The tasks and external gemspecs we used to generate binary gems are now 
    37 # obsolete. Use Patrick Hurley's gembuilder to build binary gems for any 
    38 # desired platform. 
    39 # To build a binary gem on Win32, ensure that the include and lib paths 
    40 # both contain the proper references to OPENSSL. Use the static version 
    41 # of the libraries, not the dynamic, otherwise we expose the user to a 
    42 # runtime dependency. 
    43  
    44 =begin 
    45 # To build a binary gem for win32, first build rubyeventmachine.so 
    46 # using VC6 outside of the build tree (the normal way: ruby extconf.rb, 
    47 # and then nmake). Then copy rubyeventmachine.so into the lib directory, 
    48 # and run rake gemwin32. 
    49 specwin32 = eval(File.read("eventmachine-win32.gemspec")) 
    50 specwin32.version = $version 
    51 desc "Build the RubyGem for EventMachine-win32" 
    52 task :gemwin32 => ["pkg/eventmachine-win32-#{$version}.gem"] 
    53 Rake::GemPackageTask.new(specwin32) do |g| 
    54   if $can_minitar 
    55     g.need_tar    = false 
    56     g.need_zip    = false 
     53desc "Build extension (or EVENTMACHIINE_LIBRARY) and place in lib" 
     54build_task = 'ext:build' 
     55build_task = 'java:build' if $eventmachine_library == :java 
     56build_task = :dummy_build if $eventmachine_library == :pure_ruby 
     57task :build => build_task do |t| 
     58  Dir.glob('{ext,java/src}/*.{so,bundle,dll,jar}').each do |f| 
     59    mv f, "lib" 
    5760  end 
    58   g.package_dir = "pkg" 
    5961end 
    6062 
     63task :dummy_build 
    6164 
    62 # To build a binary gem for unix platforms, first build rubyeventmachine.so 
    63 # using gcc outside of the build tree (the normal way: ruby extconf.rb, 
    64 # and then make). Then copy rubyeventmachine.so into the lib directory, 
    65 # and run rake gembinary. 
    66 specbinary = eval(File.read("eventmachine-binary.gemspec")) 
    67 specbinary.version = $version 
    68 desc "Build the RubyGem for EventMachine-Binary" 
    69 task :gembinary => ["pkg/eventmachine-binary-#{$version}.gem"] 
    70 Rake::GemPackageTask.new(specbinary) do |g| 
    71   if $can_minitar 
    72     g.need_tar    = false 
    73     g.need_zip    = false 
     65# Basic clean definition, this is enhanced by imports aswell. 
     66task :clean do 
     67  chdir 'ext' do 
     68    sh 'make clean' if test ?e, 'Makefile' 
    7469  end 
    75   g.package_dir = "pkg" 
     70  Dir.glob('**/Makefile').each { |file| rm file } 
     71  Dir.glob('**/*.{o,so,bundle,class,jar,dll,log}').each { |file| rm file } 
    7672end 
    7773 
     74Spec = Gem::Specification.new do |s| 
     75  s.name              = "eventmachine" 
     76  s.summary           = "Ruby/EventMachine library" 
     77  s.platform          = Gem::Platform::RUBY 
    7878 
    79 spec = eval(File.read("eventmachine.gemspec")) 
    80 =end 
     79  s.has_rdoc          = true 
     80  s.rdoc_options      = %w(--title EventMachine --main docs/README --line-numbers) 
     81  s.extra_rdoc_files  = Dir['docs/*'] 
    8182 
    82 spec = Gem::Specification.new do |s| 
    83         s.name              = "eventmachine" 
    84         s.summary           = "Ruby/EventMachine library" 
    85         s.platform          = Gem::Platform::RUBY 
     83  s.files             = %w(Rakefile) + Dir["{bin,tests,lib,ext,java,tasks}/**/*"] 
    8684 
    87         s.has_rdoc          = true 
    88         s.rdoc_options      = %w(--title EventMachine --main README --line-numbers) 
    89         s.extra_rdoc_files = ["README", 
    90                                 "RELEASE_NOTES", 
    91                                 "COPYING", 
    92                                 "EPOLL", 
    93                                 "GNU", 
    94                                 "LEGAL", 
    95                                 "TODO", 
    96                                 "KEYBOARD", 
    97                                 "LIGHTWEIGHT_CONCURRENCY", 
    98                                 "PURE_RUBY", 
    99                                 "SMTP", 
    100                                 "SPAWNED_PROCESSES", 
    101                                 "DEFERRABLES" 
    102                                 ] 
     85  s.require_path      = 'lib' 
    10386 
    104         s.files             = FileList["{bin,tests,lib,ext}/**/*"].exclude("rdoc").to_a 
     87  s.test_file         = "tests/testem.rb" 
     88  s.extensions        = "Rakefile" 
    10589 
    106         s.require_paths     = ["lib"] 
     90  s.author            = "Francis Cianfrocca" 
     91  s.email             = "garbagecat10@gmail.com" 
     92  s.rubyforge_project = 'eventmachine' 
     93  s.homepage          = "http://rubyeventmachine.com" 
    10794 
    108         s.test_file         = "tests/testem.rb" 
    109         s.extensions        = "ext/extconf.rb" 
     95  # Pulled in from readme, as code to pull from readme was not working! 
     96  # Might be worth removing as no one seems to use gem info anyway. 
     97  s.description = <<-EOD 
     98EventMachine implements a fast, single-threaded engine for arbitrary network 
     99communications. It's extremely easy to use in Ruby. EventMachine wraps all 
     100interactions with IP sockets, allowing programs to concentrate on the 
     101implementation of network protocols. It can be used to create both network 
     102servers and clients. To create a server or client, a Ruby program only needs 
     103to specify the IP address and port, and provide a Module that implements the 
     104communications protocol. Implementations of several standard network protocols 
     105are provided with the package, primarily to serve as examples. The real goal 
     106of EventMachine is to enable programs to easily interface with other programs 
     107using TCP/IP, especially if custom protocols are required. 
     108  EOD 
    110109 
    111         s.author            = "Francis Cianfrocca" 
    112         s.email             = "garbagecat10@gmail.com" 
    113         s.rubyforge_project = %q(eventmachine) 
    114         s.homepage          = "http://rubyeventmachine.com" 
    115  
    116  
    117         description = [] 
    118         File.open("README") do |file| 
    119                 file.each do |line| 
    120                         line.chomp! 
    121                         break if line.empty? 
    122                         description << "#{line.gsub(/\[\d\]/, '')}" 
    123                 end 
    124         end 
    125         s.description = description[1..-1].join(" ") 
     110  require 'lib/eventmachine_version' 
     111  s.version = EventMachine::VERSION 
    126112end 
    127113 
    128 spec.version = $version 
    129 desc "Build the EventMachine RubyGem" 
    130 task :gem => ["pkg/eventmachine-#{$version}.gem"] 
    131 Rake::GemPackageTask.new(spec) do |g| 
    132   if $can_minitar 
    133     g.need_tar    = false 
    134     g.need_zip    = false 
    135   end 
    136   g.package_dir = "pkg" 
    137 end 
    138  
    139  
    140 jspec = Gem::Specification.new do |s| 
    141         s.name              = "eventmachine-java" 
    142         s.summary           = "Ruby/EventMachine library" 
    143         s.platform          = Gem::Platform::RUBY 
    144  
    145         s.has_rdoc          = true 
    146         s.rdoc_options      = %w(--title EventMachine --main README --line-numbers) 
    147         s.extra_rdoc_files = ["README", "RELEASE_NOTES", "COPYING", "GNU", "LEGAL", "TODO"] 
    148  
    149         s.files             = FileList["{lib}/**/*"].exclude("rdoc").to_a 
    150  
    151         s.require_paths     = ["lib"] 
    152  
    153         s.author            = "Francis Cianfrocca" 
    154         s.email             = "garbagecat10@gmail.com" 
    155         s.rubyforge_project = %q(eventmachine) 
    156         s.homepage          = "http://rubyeventmachine.com" 
    157  
    158  
    159         description = [] 
    160         File.open("README") do |file| 
    161                 file.each do |line| 
    162                         line.chomp! 
    163                         break if line.empty? 
    164                         description << "#{line.gsub(/\[\d\]/, '')}" 
    165                 end 
    166         end 
    167         s.description = description[1..-1].join(" ") 
    168 end 
    169  
    170  
    171 jspec.version = $version 
    172 desc "Build the EventMachine RubyGem for JRuby" 
    173 task :jgem => ["pkg/eventmachine-java-#{$version}.gem"] 
    174 Rake::GemPackageTask.new(jspec) do |g| 
    175         $>.puts "-----------------" 
    176         $>.puts "Before executing the :jgem task, be sure to run :clean, and" 
    177         $>.puts "then make sure an up-to-date em_reactor.jar is present in the" 
    178         $>.puts "lib directory." 
    179         $>.puts "-----------------" 
    180   if $can_minitar 
    181     g.need_tar    = false 
    182     g.need_zip    = false 
    183   end 
    184   g.package_dir = "pkg" 
    185 end 
    186  
    187  
    188 desc "Clean extension and JAR builds out of the lib directory" 
    189 task :clean do |t| 
    190         files = %W(lib/*.so lib/*.jar) 
    191         files = FileList[files.map { |file| File.join(".", file) }].to_a 
    192         files.each {|f| 
    193                 $>.puts "unlinking file: #{f}" 
    194                 File.unlink f 
    195         } 
    196 end 
    197  
    198  
    199 if $can_minitar 
    200   desc "Build #$name .tar.gz distribution." 
    201   task :tar => [ $tardist ] 
    202   file $tardist => [ ] do |t| 
    203     current = File.basename(Dir.pwd) 
    204     Dir.chdir("..") do 
    205       begin 
    206         files = %W(ext/**/*.rb ext/**/*.cpp ext/**/*.h bin/**/* lib/**/* tests/**/* README COPYING 
    207                  GNU LEGAL RELEASE_NOTES INSTALL EPOLL TODO KEYBOARD  
    208                 LIGHTWEIGHT_CONCURRENCY PURE_RUBY SMTP SPAWNED_PROCESSES DEFERRABLES setup.rb ) 
    209         files = FileList[files.map { |file| File.join(current, file) }].to_a 
    210         files = files.select {|f| f !~ /lib\/.*[\.](so|jar)\Z/i } # remove any so or jar files in the lib directory 
    211         files.map! do |dd| 
    212           ddnew = dd.gsub(/^#{current}/, $distdir) 
    213           mtime = $release_date || File.stat(dd).mtime 
    214           if File.directory?(dd) 
    215             { :name => ddnew, :mode => 0755, :dir => true, :mtime => mtime } 
    216           else 
    217             if dd =~ %r{bin/} 
    218               mode = 0755 
    219             else 
    220               mode = 0644 
    221             end 
    222             data = File.open(dd, "rb") { |ff| ff.read } 
    223             { :name => ddnew, :mode => mode, :data => data, :size => 
    224               data.size, :mtime => mtime } 
    225           end 
    226         end 
    227  
    228         ff = File.open(t.name.gsub(%r{^\.\./}o, ''), "wb") 
    229         gz = Zlib::GzipWriter.new(ff) 
    230         tw = Archive::Tar::Minitar::Writer.new(gz) 
    231  
    232         files.each do |entry| 
    233           if entry[:dir] 
    234             tw.mkdir(entry[:name], entry) 
    235           else 
    236             tw.add_file_simple(entry[:name], entry) { |os| os.write(entry[:data]) } 
    237           end 
    238         end 
    239       ensure 
    240         tw.close if tw 
    241         gz.finish if gz 
    242         ff.close if ff 
    243       end 
    244     end 
    245   end 
    246   task $tardist => [ ] 
    247 end 
    248  
    249  
    250  
    251  
    252  
    253 # This is used by several rake tasks, that parameterize the 
    254 # behavior so we can use the same tests to test both the 
    255 # extension and non-extension versions. 
    256 def run_tests t, libr, test_filename_filter="test_*.rb" 
    257   require 'test/unit/testsuite' 
    258   require 'test/unit/ui/console/testrunner' 
    259  
    260   runner = Test::Unit::UI::Console::TestRunner 
    261  
    262   $eventmachine_library = ((RUBY_PLATFORM =~ /java/) ? :java : libr) 
    263   $LOAD_PATH.unshift('tests') 
    264   $stderr.puts "Checking for test cases:" #if t.verbose 
    265  
    266   if test_filename_filter.is_a?(Array) 
    267     test_filename_filter.each {|testcase| 
    268       $stderr.puts "\t#{testcase}" 
    269       load "tests/#{testcase}" 
    270     } 
    271   else 
    272     Dir["tests/#{test_filename_filter}"].each do |testcase| 
    273       $stderr.puts "\t#{testcase}" #if t.verbose 
    274       load testcase 
     114namespace :ext do 
     115  desc "Build C++ extension" 
     116  task :build => [:clean, :make] 
     117   
     118  desc "make extension" 
     119  task :make => [:makefile] do 
     120    chdir 'ext' do 
     121      sh 'make' 
    275122    end 
    276123  end 
    277124 
    278   suite = Test::Unit::TestSuite.new($name) 
    279  
    280   ObjectSpace.each_object(Class) do |testcase| 
    281     suite << testcase.suite if testcase < Test::Unit::TestCase 
     125  desc 'Compile the makefile' 
     126  task :makefile do |t| 
     127    chdir 'ext' do 
     128      ruby 'extconf.rb' 
     129    end 
    282130  end 
    283  
    284   runner.run(suite) 
    285131end 
    286  
    287 desc "Run tests for #$name." 
    288 task :test do |t| 
    289   run_tests t, nil 
     132   
     133namespace :java do 
     134  # This task creates the JRuby JAR file and leaves it in the lib directory. 
     135  # This step is required before executing the jgem task. 
     136  desc "Build java extension" 
     137  task :build => [:jar] do |t| 
     138    chdir('java/src') do 
     139      mv 'em_reactor.jar', '../../lib/em_reactor.jar' 
     140    end 
     141  end 
     142   
     143  desc "compile .java to .class" 
     144  task :compile do 
     145    chdir('java/src') do 
     146      sh 'javac com/rubyeventmachine/*.java' 
     147    end 
     148  end 
     149   
     150  desc "compile .classes to .jar" 
     151  task :jar => [:compile] do 
     152    chdir('java/src') do 
     153      sh "jar -cf em_reactor.jar com/rubyeventmachine/*.class" 
     154    end 
     155  end 
    290156end 
    291  
    292 desc "Run tests for #$name." 
    293 task :test_partial do |t| 
    294   run_tests t, :extension, [ 
    295     "test_basic.rb", 
    296     "test_epoll.rb", 
    297     "test_errors.rb", 
    298     "test_eventables.rb", 
    299     "test_exc.rb", 
    300     "test_futures.rb", 
    301     "test_hc.rb", 
    302     "test_httpclient2.rb", 
    303     "test_httpclient.rb", 
    304     "test_kb.rb", 
    305     #"test_ltp2.rb", 
    306     "test_ltp.rb", 
    307     "test_next_tick.rb", 
    308     "test_processes.rb", 
    309     "test_pure.rb", 
    310     "test_running.rb", 
    311     "test_sasl.rb", 
    312     #"test_send_file.rb", 
    313     "test_servers.rb", 
    314     "test_smtpclient.rb", 
    315     "test_smtpserver.rb", 
    316     "test_spawn.rb", 
    317     "test_timers.rb", 
    318     "test_ud.rb", 
    319   ] 
    320 end 
    321  
    322  
    323 desc "Run pure-ruby tests for #$name." 
    324 task :testpr do |t| 
    325   run_tests t, :pure_ruby 
    326 end 
    327  
    328 desc "Run extension tests for #$name." 
    329 task :testext do |t| 
    330   run_tests t, :extension 
    331 end 
    332  
    333 desc "PROVISIONAL: run tests for user-defined events" 
    334 task :test_ud do |t| 
    335   run_tests t, :extension, "test_ud.rb" 
    336 end 
    337  
    338 desc "PROVISIONAL: run tests for line/text protocol handler" 
    339 task :test_ltp do |t| 
    340   run_tests t, :extension, "test_ltp*.rb" 
    341 end 
    342  
    343 desc "PROVISIONAL: run tests for header/content protocol handler" 
    344 task :test_hc do |t| 
    345   run_tests t, :extension, "test_hc.rb" 
    346 end 
    347  
    348 desc "PROVISIONAL: run tests for exceptions" 
    349 task :test_exc do |t| 
    350   run_tests t, :extension, "test_exc.rb" 
    351 end 
    352  
    353 desc "Test protocol handlers" 
    354 task :test_protocols => [ :test_hc, :test_ltp ] 
    355  
    356  
    357 desc "Test HTTP client" 
    358 task :test_httpclient do |t| 
    359   run_tests t, :extension, "test_httpclient.rb" 
    360 end 
    361  
    362 desc "Test HTTP client2" 
    363 task :test_httpclient2 do |t| 
    364   run_tests t, :extension, "test_httpclient2.rb" 
    365 end 
    366  
    367 desc "Test futures" 
    368 task :test_futures do |t| 
    369   run_tests t, :extension, "test_future*.rb" 
    370 end 
    371  
    372 desc "Test Timers" 
    373 task :test_timers do |t| 
    374   run_tests t, :extension, "test_timer*.rb" 
    375 end 
    376  
    377 desc "Test Next Tick" 
    378 task :test_next_tick do |t| 
    379   run_tests t, :extension, "test_next_tick*.rb" 
    380 end 
    381  
    382 desc "Test Epoll" 
    383 task :test_epoll do |t| 
    384   run_tests t, :extension, "test_epoll*.rb" 
    385 end 
    386  
    387 desc "Test Servers" 
    388 task :test_servers do |t| 
    389   run_tests t, :extension, "test_servers*.rb" 
    390 end 
    391  
    392 desc "Test Basic" 
    393 task :test_basic do |t| 
    394   run_tests t, :extension, "test_basic*.rb" 
    395 end 
    396  
    397 desc "Test Send File" 
    398 task :test_send_file do |t| 
    399   run_tests t, :extension, "test_send_file*.rb" 
    400 end 
    401  
    402 desc "Test Running" 
    403 task :test_running do |t| 
    404   run_tests t, :extension, "test_running*.rb" 
    405 end 
    406  
    407 desc "Test Keyboard Events" 
    408 task :test_keyboard do |t| 
    409   run_tests t, :extension, "test_kb*.rb" 
    410 end 
    411  
    412 desc "Test Spawn" 
    413 task :test_spawn do |t| 
    414   run_tests t, :spawn, "test_spawn*.rb" 
    415 end 
    416  
    417 desc "Test SMTP" 
    418 task :test_smtp do |t| 
    419   run_tests t, :extension, "test_smtp*.rb" 
    420 end 
    421  
    422 desc "Test Errors" 
    423 task :test_errors do |t| 
    424   run_tests t, :extension, "test_errors*.rb" 
    425 end 
    426  
    427 desc "Test Pure Ruby" 
    428 task :test_pure do |t| 
    429   run_tests t, :extension, "test_pure*.rb" 
    430 end 
    431  
    432 desc "Test Processes" 
    433 task :test_processes do |t| 
    434   run_tests t, :extension, "test_process*.rb" 
    435 end 
    436  
    437 desc "Test SASL" 
    438 task :test_sasl do |t| 
    439   run_tests t, :extension, "test_sasl*.rb" 
    440 end 
    441  
    442 desc "Test Attach" 
    443 task :test_attach do |t| 
    444   run_tests t, :extension, "test_attach*.rb" 
    445 end 
    446  
    447  
    448 desc "Build everything" 
    449 task :default => [ :gem ] 
    450  
    451  
    452  
    453 # This task is useful for development. 
    454 desc "Compile the extension." 
    455 task :extension do |t| 
    456         Dir.mkdir "nonversioned" unless File.directory?("nonversioned") 
    457         Dir.chdir "nonversioned" 
    458         system "ruby ../ext/extconf.rb" 
    459         system "make clean" 
    460         system "make" 
    461         system "cp *.so ../lib" or system "copy *.so ../lib" 
    462         Dir.chdir ".." 
    463 end 
    464  
    465  
    466 # This task creates the JRuby JAR file and leaves it in the lib directory. 
    467 # This step is required before executing the jgem task. 
    468 desc "Compile the JAR" 
    469 task :jar do |t| 
    470         p "JAR?" 
    471 end 
    472  
  • trunk/tasks/tests.rake

    r723 r788  
    22# behavior so we can use the same tests to test both the 
    33# extension and non-extension versions. 
    4 def run_tests t, libr, test_filename_filter="test_*.rb" 
     4def run_tests t, libr = :cascade, test_files="test_*.rb" 
    55  require 'test/unit/testsuite' 
    66  require 'test/unit/ui/console/testrunner' 
    7  
     7  require 'tests/testem' 
     8   
     9  base_dir = File.expand_path(File.dirname(__FILE__) + '/../') + '/' 
     10   
    811  runner = Test::Unit::UI::Console::TestRunner 
    9  
    10   $eventmachine_library = ((RUBY_PLATFORM =~ /java/) ? :java : libr) 
    11   $LOAD_PATH.unshift('tests') 
    12   $stderr.puts "Checking for test cases:" #if t.verbose 
    13  
    14   if test_filename_filter.is_a?(Array) 
    15     test_filename_filter.each {|testcase| 
    16       $stderr.puts "\t#{testcase}" 
    17       load "tests/#{testcase}" 
    18     } 
    19   else 
    20     Dir["tests/#{test_filename_filter}"].each do |testcase| 
    21       $stderr.puts "\t#{testcase}" #if t.verbose 
    22       load testcase 
    23     end 
    24   end 
    25  
     12   
     13  $eventmachine_library = libr 
     14  EmTestRunner.run(test_files) 
     15   
    2616  suite = Test::Unit::TestSuite.new($name) 
    2717 
     
    3525desc "Run tests for #{Spec.name}." 
    3626task :test do |t| 
    37   run_tests t, nil 
     27  # run_tests t 
     28  # Rake +/ friends leave threads, etc, less stable test runs. 
     29  ruby "-Ilib -Iext -Ijava tests/testem.rb #{'-v' if ENV['VERBOSE']}" 
    3830end 
    3931 
     
    5345      "test_httpclient.rb", 
    5446      "test_kb.rb", 
    55       #"test_ltp2.rb", 
     47      "test_ltp2.rb", 
    5648      "test_ltp.rb", 
    5749      "test_next_tick.rb", 
     
    6759      "test_timers.rb", 
    6860      "test_ud.rb", 
    69     ] 
     61    ].map { |tf| "tests/#{tf}" } 
    7062  end 
    7163   
     
    166158  desc "Test Spawn" 
    167159  task :spawn do |t| 
    168     run_tests t, :spawn, "test_spawn*.rb" 
     160    run_tests t, :extension, "test_spawn*.rb" 
    169161  end 
    170162 
     
    193185    run_tests t, :java, "test_sasl*.rb" 
    194186  end 
     187   
     188  desc "Test Attach" 
     189  task :attach do |t| 
     190    run_tests t, :extension, "test_attach*.rb" 
     191  end 
    195192end 
  • trunk/tests/test_basic.rb

    r735 r788  
    2525#  
    2626 
    27 $:.unshift "../lib" 
     27$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib") 
    2828require 'eventmachine' 
    2929require 'test/unit' 
     
    3232 
    3333  def setup 
     34    assert(!EM.reactor_running?) 
    3435  end 
    3536 
    3637  def teardown 
     38    assert(!EM.reactor_running?) 
    3739  end 
    3840 
     
    4143  def test_libtype 
    4244    lt = EventMachine.library_type 
    43     case (ENV["EVENTMACHINE_LIBRARY"] || $eventmachine_library || :xxx).to_sym 
     45                em_lib = (ENV["EVENTMACHINE_LIBRARY"] || $eventmachine_library || :xxx).to_sym 
     46                 
     47                # Running from test runner, under jruby. 
     48                if RUBY_PLATFORM == 'java' 
     49                        unless em_lib == :pure_ruby 
     50                                assert_equal( :java, lt ) 
     51                                return 
     52                        end 
     53                end 
     54                 
     55    case em_lib 
    4456    when :pure_ruby 
    4557      assert_equal( :pure_ruby, lt ) 
     
    4961      assert_equal( :java, lt ) 
    5062    else 
    51       assert_equal( :extension, lt ) 
     63                        # Running from jruby as a standalone test. 
     64                        if RUBY_PLATFORM == 'java' 
     65                                assert_equal( :java, lt ) 
     66                        else 
     67        assert_equal( :extension, lt ) 
     68                        end 
    5269    end 
    5370  end 
     
    6986    n = 0 
    7087    EventMachine.run { 
    71       EventMachine.add_periodic_timer(1) { 
     88      EventMachine.add_periodic_timer(0.1) { 
    7289        n += 1 
    7390        EventMachine.stop if n == 2 
     
    99116  # even after the supplied block completes. 
    100117  def test_run_block 
    101           a = nil 
    102           EM.run_block { a = "Worked" } 
    103           assert a 
     118    assert !EM.reactor_running? 
     119      a = nil 
     120      EM.run_block { a = "Worked" } 
     121      assert a 
     122      assert !EM.reactor_running? 
    104123  end 
    105124 
     
    137156          } 
    138157  end 
    139  
    140158 
    141159  #------------------------------------ 
     
    164182          end 
    165183  end 
    166   def test_post_init_error 
    167           assert_raise( NameError ) { 
     184  # This test causes issues, the machine becomes unreleasable after  
     185  # release_machine suffers an exception in event_callback. 
     186  def xxx_test_post_init_error 
     187          assert_raise( EventMachine::ConnectionNotBound ) { 
    168188                  EM.run { 
    169189                        EM::Timer.new(1) {EM.stop} 
     
    172192                  } 
    173193          } 
    174   end 
    175  
     194          EM.run { 
     195            EM.stop 
     196          } 
     197          assert !EM.reactor_running? 
     198  end 
     199   
     200  module BrsTestSrv 
     201    def receive_data data 
     202      $received << data 
     203    end 
     204    def unbind 
     205      EM.stop 
     206    end 
     207  end 
     208  module BrsTestCli 
     209    def post_init 
     210      send_data $sent 
     211      close_connection_after_writing 
     212    end 
     213  end 
     214   
     215  # From ticket #50 
     216  def test_byte_range_send 
     217    $received = '' 
     218    $sent = (0..255).to_a.pack('C*') 
     219    EM::run { 
     220       
     221      EM::start_server TestHost, TestPort, BrsTestSrv 
     222       
     223      EM::connect TestHost, TestPort, BrsTestCli 
     224       
     225      EM::add_timer(0.5) { assert(false, 'test timed out'); EM.stop; Kernel.warn "test timed out!" } 
     226    } 
     227    assert_equal($sent, $received) 
     228  end 
    176229 
    177230end 
  • trunk/tests/test_defer.rb

    r668 r788  
    3131class TestDeferUsage < Test::Unit::TestCase 
    3232 
    33         def setup 
    34         end 
    35  
    36         def teardown 
    37         end 
    38  
    39         def run_em_with_defers 
    40                 n = 0 
    41                 n_times = 20 
    42                 EM.run { 
    43                         n_times.times { 
    44                                 EM.defer proc { 
    45                                         sleep 0.1 
    46                                 }, proc { 
    47                                         n += 1 
    48                                         EM.stop if n == n_times 
    49                                 } 
    50                         } 
    51                 } 
    52                 assert_equal( n, n_times ) 
    53         end 
    54         def test_defers 
    55                 10.times { 
    56                         run_em_with_defers {|n,ntimes| 
    57                                 assert_equal( n, ntimes ) 
    58                         } 
    59                 } 
    60         end 
     33  def test_defers 
     34    n = 0 
     35    n_times = 20 
     36    EM.run { 
     37      n_times.times { 
     38        work_proc = proc { n += 1 } 
     39        callback = proc { EM.stop if n == n_times } 
     40        EM.defer work_proc, callback 
     41      } 
     42    } 
     43    assert_equal( n, n_times ) 
     44  end 
    6145 
    6246end 
  • trunk/tests/testem.rb

    r668 r788  
    11# $Id$ 
    2 # 
    3 # STUB 
    4 # 
    52 
     3require 'test/unit' 
     4 
     5module EmTestRunner 
     6  @em_root = File.expand_path(File.dirname(__FILE__) + '/../') 
     7  @lib_dir = File.join(@em_root, 'lib') 
     8  @ext_dir = File.join(@em_root, 'ext') 
     9  @java_dir = File.join(@em_root, 'java') 
     10 
     11  def self.run(glob = 'test_*.rb') 
     12    $:.unshift(@lib_dir) 
     13    $:.unshift(@ext_dir) 
     14    $:.unshift(@java_dir) 
     15 
     16    case glob 
     17    when Array 
     18      files = glob 
     19    else 
     20      files = Dir[File.dirname(__FILE__) + '/' + glob] 
     21    end 
     22 
     23    files.each do |tc| 
     24      require tc 
     25    end 
     26  end 
     27end 
     28 
     29if __FILE__ == $0 
     30  EmTestRunner.run 
     31end 
  • trunk/tests/test_epoll.rb

    r668 r788  
    2929# 
    3030 
    31 $:.unshift "../lib" 
    3231require 'eventmachine' 
    3332require 'test/unit' 
     
    3534 
    3635class TestEpoll < Test::Unit::TestCase 
    37  
    38         def setup 
    39         end 
    40  
    41         def teardown 
    42         end 
    43  
    4436 
    4537        module TestEchoServer 
     
    9890        end 
    9991 
    100        def test_defer 
    101                $n = 0 
    102                 EM.epoll 
    103                 EM.run { 
    104                         sleep_proc = proc {sleep 1} 
    105                         return_proc = proc {$n += 1; EM.stop} 
    106                        EM.defer sleep_proc, return_proc 
    107                
    108                assert_equal( 1, $n ) 
    109        end 
     92  def test_defer 
     93    n = 0 
     94    work_proc = proc {n += 1} 
     95    callback_proc = proc {EM.stop} 
     96    EM.epoll 
     97    EM.run { 
     98      EM.defer work_proc, callback_proc 
     99   
     100    assert_equal( 1, n ) 
     101  end 
    110102 
    111103 
     
    160152                                EM.connect_unix_domain(fn, TestEchoClient) {$n += 1} 
    161153                        } 
     154                        EM::add_timer(1) { $stderr.puts("test_unix_domain timed out!"); EM::stop } 
    162155                } 
    163156                assert_equal(0, $n) 
  • trunk/tests/test_hc.rb

    r721 r788  
    2525# 
    2626 
    27 $:.unshift "../lib" 
     27# $:.unshift "../lib" 
    2828require 'eventmachine' 
    29 require 'socket' 
    3029require 'test/unit' 
    3130 
    32 # This doesn't completely work under Ruby 1.9. 
    33 # Part of it is thread race conditions. I added some sleeps to make these 
    34 # tests work. Native threads do strange things when you do I/O on them. 
    35 # 
    36 # And it's even worse in Java, where I/O on native threads doesn't seem 
    37 # to be reliable at all. 
    38 # 
    39  
    40  
    4131class TestHeaderAndContentProtocol < Test::Unit::TestCase 
    4232 
    43         TestHost = "127.0.0.1" 
    44         TestPort = 8905 
    45  
    46  
    47         #-------------------------------------------------------------------- 
    48  
    49         class SimpleTest < EventMachine::Protocols::HeaderAndContentProtocol 
    50                 attr_reader :first_header, :my_headers, :request 
    51  
    52                 def receive_first_header_line hdr 
    53                         @first_header ||= [] 
    54                         @first_header << hdr 
    55                 end 
    56                 def receive_headers hdrs 
    57                         @my_headers ||= [] 
    58                         @my_headers << hdrs 
    59                 end 
    60                 def receive_request hdrs, content 
    61                         @request ||= [] 
    62                         @request << [hdrs, content] 
    63                 end 
    64         end 
    65  
    66  
    67         def test_no_content 
    68                 Thread.abort_on_exception = true 
    69                 the_connection = nil 
    70                 EventMachine.run { 
    71                         EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
    72                                 the_connection = conn 
    73                         end 
    74                         EventMachine.add_timer(4) {raise "test timed out"} 
    75  
    76                         pr = proc { 
    77                                 t = TCPSocket.new TestHost, TestPort 
    78                                 t.write [ "aaa\n", "bbb\r\n", "ccc\n", "\n" ].join 
    79                                 t.close 
    80                         } 
    81  
    82                         if RUBY_PLATFORM =~ /java/i 
    83                                 pr.call 
    84                                 EM.add_timer(0.5) {EM.stop} 
    85                         else 
    86                                 EventMachine.defer proc { 
    87                                         pr.call 
    88                                         if RUBY_VERSION =~ /\A1\.9\./ 
    89                                                 sleep 0.1 
    90                                                 STDERR.puts "Introducing extraneous sleep for Ruby 1.9" 
    91                                         end 
    92                                 }, proc { 
    93                                         EventMachine.stop 
    94                                 } 
    95                         end 
    96                 } 
    97                 assert_equal( ["aaa"], the_connection.first_header ) 
    98                 assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers ) 
    99                 assert_equal( [[%w(aaa bbb ccc), ""]], the_connection.request ) 
    100         end 
    101  
    102  
    103  
    104  
    105         def test_content 
    106                 Thread.abort_on_exception = true 
    107                 the_connection = nil 
    108                 content = "A" * 50 
    109                 headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"] 
    110                 EventMachine.run { 
    111                         EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
    112                                 the_connection = conn 
    113                         end 
    114                         EventMachine.add_timer(4) {raise "test timed out"} 
    115  
    116                         pr = proc { 
    117                                 t = TCPSocket.new TestHost, TestPort 
    118                                 headers.each {|h| t.write "#{h}\r\n" } 
    119                                 t.write "\n" 
    120                                 t.write content 
    121                                 t.close 
    122                         } 
    123  
    124                         if RUBY_PLATFORM =~ /java/i 
    125                                 # I/O on threads seems completely unreliable in Java. 
    126                                 pr.call 
    127                                 EM.add_timer(0.5) {EM.stop} 
    128                         else 
    129                                 EventMachine.defer proc { 
    130                                         pr.call 
    131                                         if RUBY_VERSION =~ /\A1\.9\./ 
    132                                                 sleep 0.1 
    133                                                 STDERR.puts "Introducing extraneous sleep for Ruby 1.9" 
    134                                         end 
    135                                 }, proc { 
    136                                         EM.stop 
    137                                 } 
    138                         end 
    139                 } 
    140                 assert_equal( ["aaa"], the_connection.first_header ) 
    141                 assert_equal( [headers], the_connection.my_headers ) 
    142                 assert_equal( [[headers, content]], the_connection.request ) 
    143         end 
    144  
    145  
    146  
    147         def test_several_requests 
    148                 Thread.abort_on_exception = true 
    149                 the_connection = nil 
    150                 content = "A" * 50 
    151                 headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"] 
    152                 EventMachine.run { 
    153                         EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
    154                                 the_connection = conn 
    155                         end 
    156                         EventMachine.add_timer(4) {raise "test timed out"} 
    157  
    158                         pr = proc { 
    159                                 t = TCPSocket.new TestHost, TestPort 
    160                                 5.times { 
    161                                         headers.each {|h| t.write "#{h}\r\n" } 
    162                                         t.write "\n" 
    163                                         t.write content 
    164                                 } 
    165                                 t.close 
    166                         } 
    167  
    168                         if RUBY_PLATFORM =~ /java/i 
    169                                 pr.call 
    170                                 EM.add_timer(1) {EM.stop} 
    171                         else 
    172                                 EventMachine.defer proc { 
    173                                         pr.call 
    174                                         if RUBY_VERSION =~ /\A1\.9\./ 
    175                                                 sleep 0.1 
    176                                                 STDERR.puts "Introducing extraneous sleep for Ruby 1.9" 
    177                                         end 
    178                                 }, proc { 
    179                                         EventMachine.stop 
    180                                 } 
    181                         end 
    182                 } 
    183                 assert_equal( ["aaa"] * 5, the_connection.first_header ) 
    184                 assert_equal( [headers] * 5, the_connection.my_headers ) 
    185                 assert_equal( [[headers, content]] * 5, the_connection.request ) 
    186         end 
    187  
    188  
    189     def x_test_multiple_content_length_headers 
    190         # This is supposed to throw a RuntimeError but it throws a C++ exception instead. 
    191         Thread.abort_on_exception = true 
    192         the_connection = nil 
    193         content = "A" * 50 
    194         headers = ["aaa", "bbb", ["Content-length: #{content.length}"]*2, "ccc"].flatten 
    195         EventMachine.run { 
    196             EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
    197                 the_connection = conn 
    198             end 
    199             EventMachine.add_timer(4) {raise "test timed out"} 
    200             EventMachine.defer proc { 
    201                 t = TCPSocket.new TestHost, TestPort 
    202                 headers.each {|h| t.write "#{h}\r\n" } 
    203                 t.write "\n" 
    204                 t.write content 
    205                 t.close 
    206             }, proc { 
    207                 EventMachine.stop 
    208             } 
    209         } 
     33  TestHost = "127.0.0.1" 
     34  TestPort = 8905 
     35 
     36  class SimpleTest < EventMachine::Protocols::HeaderAndContentProtocol 
     37    attr_reader :first_header, :my_headers, :request 
     38 
     39    def receive_first_header_line hdr 
     40      @first_header ||= [] 
     41      @first_header << hdr 
    21042    end 
    211  
    212         def test_interpret_headers 
    213                 Thread.abort_on_exception = true 
    214                 the_connection = nil 
    215                 content = "A" * 50 
    216                 headers = [ 
    217                         "GET / HTTP/1.0", 
    218                         "Accept: aaa", 
    219                         "User-Agent: bbb", 
    220                         "Host:      ccc", 
    221                         "x-tempest-header:ddd" 
    222                 ] 
    223  
    224                 EventMachine.run { 
    225                         EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
    226                                 the_connection = conn 
    227                         end 
    228                         EventMachine.add_timer(4) {raise "test timed out"} 
    229  
    230                         pr = proc { 
    231                                 t = TCPSocket.new TestHost, TestPort 
    232                                 headers.each {|h| t.write "#{h}\r\n" } 
    233                                 t.write "\n" 
    234                                 t.write content 
    235                                 t.close 
    236                         } 
    237  
    238                         if RUBY_PLATFORM =~ /java/i 
    239                                 pr.call 
    240                                 EM.add_timer(0.5) {EM.stop} 
    241                         else 
    242                                 EventMachine.defer proc { 
    243                                         pr.call 
    244                                         if RUBY_VERSION =~ /\A1\.9\./ 
    245                                                 sleep 0.1 
    246                                                 STDERR.puts "Introducing extraneous sleep for Ruby 1.9" 
    247                                         end 
    248                                 }, proc { 
    249                                         EventMachine.stop 
    250                                 } 
    251                         end 
    252                 } 
    253  
    254                 hsh = the_connection.headers_2_hash( the_connection.my_headers.shift ) 
    255                 assert_equal( 
    256                         { 
    257                                 :accept => "aaa", 
    258                                 :user_agent => "bbb", 
    259                                 :host => "ccc", 
    260                                 :x_tempest_header => "ddd" 
    261                         }, 
    262                         hsh 
    263                 ) 
    264         end 
    265  
     43    def receive_headers hdrs 
     44      @my_headers ||= [] 
     45      @my_headers << hdrs 
     46    end 
     47    def receive_request hdrs, content 
     48      @request ||= [] 
     49      @request << [hdrs, content] 
     50    end 
     51  end 
     52 
     53  def test_no_content 
     54    the_connection = nil 
     55    EventMachine.run { 
     56      EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
     57        the_connection = conn 
     58      end 
     59      EventMachine.add_timer(4) {raise "test timed out"} 
     60 
     61      client = Module.new do 
     62        def unbind 
     63          EM.add_timer(0.1) { EM.stop } 
     64        end 
     65 
     66        def post_init 
     67          send_data [ "aaa\n", "bbb\r\n", "ccc\n", "\n" ].join 
     68          close_connection_after_writing 
     69        end 
     70      end 
     71 
     72      EventMachine.connect( TestHost, TestPort, client ) 
     73    } 
     74    assert_equal( ["aaa"], the_connection.first_header ) 
     75    assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers ) 
     76    assert_equal( [[%w(aaa bbb ccc), ""]], the_connection.request ) 
     77  end 
     78 
     79  def test_content 
     80    the_connection = nil 
     81    content = "A" * 50 
     82    headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"] 
     83    EventMachine.run { 
     84      EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
     85        the_connection = conn 
     86      end 
     87      EventMachine.add_timer(4) { assert(false, 'test timeout'); EM.stop } 
     88 
     89      client = Module.new do 
     90        define_method(:headers) { headers } 
     91        define_method(:content) { content } 
     92 
     93        def unbind 
     94          EM.add_timer(0.1) { EM.stop } 
     95        end 
     96 
     97        def post_init 
     98          headers.each { |h| send_data "#{h}\r\n" } 
     99          send_data "\n" 
     100          send_data content 
     101          close_connection_after_writing 
     102        end 
     103      end 
     104 
     105      EventMachine.connect( TestHost, TestPort, client ) 
     106 
     107    } 
     108    assert_equal( ["aaa"], the_connection.first_header ) 
     109    assert_equal( [headers], the_connection.my_headers ) 
     110    assert_equal( [[headers, content]], the_connection.request ) 
     111  end 
     112 
     113  def test_several_requests 
     114    the_connection = nil 
     115    content = "A" * 50 
     116    headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"] 
     117    EventMachine.run { 
     118      EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
     119        the_connection = conn 
     120      end 
     121      EventMachine.add_timer(4) { assert(false, 'test timeout'); EM.stop } 
     122 
     123      client = Module.new do 
     124        define_method(:headers) { headers } 
     125        define_method(:content) { content } 
     126 
     127        def unbind 
     128          EM.add_timer(0.1) { EM.stop } 
     129        end 
     130 
     131        def post_init 
     132          5.times do 
     133            headers.each { |h| send_data "#{h}\r\n" } 
     134            send_data "\n" 
     135            send_data content 
     136          end 
     137          close_connection_after_writing 
     138        end 
     139      end 
     140 
     141      EventMachine.connect( TestHost, TestPort, client ) 
     142    } 
     143    assert_equal( ["aaa"] * 5, the_connection.first_header ) 
     144    assert_equal( [headers] * 5, the_connection.my_headers ) 
     145    assert_equal( [[headers, content]] * 5, the_connection.request ) 
     146  end 
     147 
     148 
     149  # def x_test_multiple_content_length_headers 
     150  #   # This is supposed to throw a RuntimeError but it throws a C++ exception instead. 
     151  #   the_connection = nil 
     152  #   content = "A" * 50 
     153  #   headers = ["aaa", "bbb", ["Content-length: #{content.length}"]*2, "ccc"].flatten 
     154  #   EventMachine.run { 
     155  #     EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
     156  #       the_connection = conn 
     157  #     end 
     158  #     EventMachine.add_timer(4) {raise "test timed out"} 
     159  #     test_proc = proc { 
     160  #       t = TCPSocket.new TestHost, TestPort 
     161  #       headers.each {|h| t.write "#{h}\r\n" } 
     162  #       t.write "\n" 
     163  #       t.write content 
     164  #       t.close 
     165  #     } 
     166  #     EventMachine.defer test_proc, proc { 
     167  #       EventMachine.stop 
     168  #     } 
     169  #   } 
     170  # end 
     171 
     172  def test_interpret_headers 
     173    the_connection = nil 
     174    content = "A" * 50 
     175    headers = [ 
     176      "GET / HTTP/1.0", 
     177      "Accept: aaa", 
     178      "User-Agent: bbb", 
     179      "Host:        ccc", 
     180      "x-tempest-header:ddd" 
     181    ] 
     182 
     183    EventMachine.run { 
     184      EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn| 
     185        the_connection = conn 
     186      end 
     187      EventMachine.add_timer(4) {raise "test timed out"} 
     188 
     189      client = Module.new do 
     190        define_method(:headers) { headers } 
     191        define_method(:content) { content } 
     192 
     193        def unbind 
     194          EM.add_timer(0.1) { EM.stop } 
     195        end 
     196 
     197        def post_init 
     198          headers.each { |h| send_data "#{h}\r\n" } 
     199          send_data "\n" 
     200          send_data content 
     201          close_connection_after_writing 
     202        end 
     203      end 
     204 
     205      EventMachine.connect( TestHost, TestPort, client ) 
     206    } 
     207 
     208    hsh = the_connection.headers_2_hash( the_connection.my_headers.shift ) 
     209    expect = { 
     210      :accept => "aaa", 
     211      :user_agent => "bbb", 
     212      :host => "ccc", 
     213      :x_tempest_header => "ddd" 
     214    } 
     215    assert_equal(expect, hsh) 
     216  end 
    266217 
    267218end 
    268  
    269  
  • trunk/tests/test_ltp.rb

    r668 r788  
    2626# 
    2727 
    28 $:.unshift "../lib" 
    2928require 'eventmachine' 
    30 require 'socket' 
    3129require 'test/unit' 
    3230 
    3331class TestLineAndTextProtocol < Test::Unit::TestCase 
    3432 
    35     TestHost = "127.0.0.1" 
    36     TestPort = 8905 
     33  TestHost = "127.0.0.1" 
     34  TestPort = 8905 
    3735 
    3836 
    39     #-------------------------------------------------------------------- 
     37  #-------------------------------------------------------------------- 
    4038 
    41     class SimpleLineTest < EventMachine::Protocols::LineAndTextProtocol 
    42         def receive_line line 
    43             @line_buffer << line 
    44         end 
     39  class SimpleLineTest < EventMachine::Protocols::LineAndTextProtocol 
     40    def receive_line line 
     41      @line_buffer << line 
    4542    end 
     43  end 
    4644 
    47     def test_simple_lines 
    48         # THIS TEST CURRENTLY FAILS IN JRUBY. 
    49         assert( RUBY_PLATFORM !~ /java/ ) 
    50  
    51         lines_received = [] 
    52         Thread.abort_on_exception = true 
    53         EventMachine.run { 
    54             EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn| 
    55                 conn.instance_eval "@line_buffer = lines_received" 
    56             end 
    57             EventMachine.add_timer(4) {raise "test timed out"} 
    58             EventMachine.defer proc { 
    59                 t = TCPSocket.new TestHost, TestPort 
    60                 t.write [ 
    61                     "aaa\n", "bbb\r\n", "ccc\n" 
    62                 ].join 
    63                 t.close 
    64             }, proc { 
    65                 EventMachine.stop 
    66             } 
    67         } 
    68         assert_equal( %w(aaa bbb ccc), lines_received ) 
     45  module StopClient 
     46    def set_receive_data(&blk) 
     47      @rdb = blk 
    6948    end 
    70  
    71     #-------------------------------------------------------------------- 
    72  
    73     class SimpleLineTest < EventMachine::Protocols::LineAndTextProtocol 
    74         def receive_error text 
    75             @error_message << text 
    76         end 
     49     
     50    def receive_data data 
     51      @rdb.call(data) if @rdb 
    7752    end 
    78  
    79     def test_overlength_lines 
    80         # THIS TEST CURRENTLY FAILS IN JRUBY. 
    81         assert( RUBY_PLATFORM !~ /java/ ) 
    82  
    83         lines_received = [] 
    84         Thread.abort_on_exception = true 
    85         EventMachine.run { 
    86             EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn| 
    87                 conn.instance_eval "@error_message = lines_received" 
    88             end 
    89             EventMachine.add_timer(4) {raise "test timed out"} 
    90             EventMachine.defer proc { 
    91                 t = TCPSocket.new TestHost, TestPort 
    92                 t.write "a" * (16*1024 + 1) 
    93                 t.write "\n" 
    94                 t.close 
    95             }, proc { 
    96                 EventMachine.stop 
    97             } 
    98         } 
    99         assert_equal( ["overlength line"], lines_received ) 
     53     
     54    def unbind 
     55      EM.add_timer(0.1) { EM.stop } 
    10056    end 
     57  end 
    10158 
    10259 
    103     #-------------------------------------------------------------------- 
     60  def test_simple_lines 
     61    # THIS TEST CURRENTLY FAILS IN JRUBY. 
     62    assert( RUBY_PLATFORM !~ /java/ ) 
    10463 
    105     class LineAndTextTest < EventMachine::Protocols::LineAndTextProtocol 
    106         def post_init 
    107         end 
    108         def receive_line line 
    109             if line =~ /content-length:\s*(\d+)/i 
    110                 @content_length = $1.to_i 
    111             elsif line.length == 0 
    112                 set_binary_mode @content_length 
    113             end 
    114         end 
    115         def receive_binary_data text 
    116             send_data "received #{text.length} bytes" 
    117             close_connection_after_writing 
    118         end 
     64    lines_received = [] 
     65    Thread.abort_on_exception = true 
     66    EventMachine.run { 
     67      EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn| 
     68        conn.instance_eval "@line_buffer = lines_received" 
     69      end 
     70      EventMachine.add_timer(4) {assert(false, "test timed out")} 
     71 
     72      EventMachine.connect TestHost, TestPort, StopClient do |c| 
     73        c.send_data "aaa\nbbb\r\nccc\n" 
     74        c.close_connection_after_writing 
     75      end 
     76    } 
     77    assert_equal( %w(aaa bbb ccc), lines_received ) 
     78  end 
     79 
     80  #-------------------------------------------------------------------- 
     81 
     82  class SimpleLineTest < EventMachine::Protocols::LineAndTextProtocol 
     83    def receive_error text 
     84      @error_message << text 
    11985    end 
     86  end 
    12087 
    121     def test_lines_and_text 
    122         output = nil 
    123         lines_received = [] 
    124         text_received = [] 
    125         Thread.abort_on_exception = true 
    126         EventMachine.run { 
    127             EventMachine.start_server( TestHost, TestPort, LineAndTextTest ) do |conn| 
    128                 conn.instance_eval "@lines = lines_received; @text = text_received" 
    129             end 
    130             EventMachine.add_timer(2) {raise "test timed out"} 
    131             EventMachine.defer proc { 
    132                 t = TCPSocket.new TestHost, TestPort 
    133                 t.puts "Content-length: 400" 
    134                 t.puts 
    135                 t.write "A" * 400 
    136                 output = t.read 
    137                 t.close 
    138             }, proc { 
    139                 EventMachine.stop 
    140             } 
    141         } 
    142         assert_equal( "received 400 bytes", output ) 
    143     end 
     88  def test_overlength_lines 
     89    # THIS TEST CURRENTLY FAILS IN JRUBY. 
     90    assert( RUBY_PLATFORM !~ /java/ ) 
    14491 
    145     #-------------------------------------------------------------------- 
     92    lines_received = [] 
     93    Thread.abort_on_exception = true 
     94    EventMachine.run { 
     95      EventMachine.start_server( TestHost, TestPort, SimpleLineTest ) do |conn| 
     96        conn.instance_eval "@error_message = lines_received" 
     97      end 
     98      EventMachine.add_timer(4) {assert(false, "test timed out")} 
     99 
     100      EventMachine.connect TestHost, TestPort, StopClient do |c| 
     101        c.send_data "a" * (16*1024 + 1) 
     102        c.send_data "\n" 
     103        c.close_connection_after_writing 
     104      end 
     105 
     106    } 
     107    assert_equal( ["overlength line"], lines_received ) 
     108  end 
    146109 
    147110 
    148     class BinaryTextTest < EventMachine::Protocols::LineAndTextProtocol 
    149         def post_init 
    150         end 
    151         def receive_line line 
    152             if line =~ /content-length:\s*(\d+)/i 
    153                 set_binary_mode $1.to_i 
    154             else 
    155                 raise "protocol error" 
    156             end 
    157         end 
    158         def receive_binary_data text 
    159             send_data "received #{text.length} bytes" 
    160             close_connection_after_writing 
    161         end 
     111  #-------------------------------------------------------------------- 
     112 
     113  class LineAndTextTest < EventMachine::Protocols::LineAndTextProtocol 
     114    def post_init 
    162115    end 
     116    def receive_line line 
     117      if line =~ /content-length:\s*(\d+)/i 
     118        @content_length = $1.to_i 
     119      elsif line.length == 0 
     120        set_binary_mode @content_length 
     121      end 
     122    end 
     123    def receive_binary_data text 
     124      send_data "received #{text.length} bytes" 
     125      close_connection_after_writing 
     126    end 
     127  end 
    163128 
    164     def test_binary_text 
    165         output = nil 
    166         lines_received = [] 
    167         text_received = [] 
    168         Thread.abort_on_exception = true 
    169         EventMachine.run { 
    170             EventMachine.start_server( TestHost, TestPort, BinaryTextTest ) do |conn| 
    171                 conn.instance_eval "@lines = lines_received; @text = text_received" 
    172             end 
    173             EventMachine.add_timer(4) {raise "test timed out"} 
    174             EventMachine.defer proc { 
    175                 t = TCPSocket.new TestHost, TestPort 
    176                 t.puts "Content-length: 10000" 
    177                 t.write "A" * 10000 
    178                 output = t.read 
    179                 t.close 
    180             }, proc { 
    181                 EventMachine.stop 
    182             } 
    183         } 
    184         assert_equal( "received 10000 bytes", output ) 
    185     end 
     129  def test_lines_and_text 
     130    output = '' 
     131    lines_received = [] 
     132    text_received = [] 
     133    Thread.abort_on_exception = true 
     134    EventMachine.run { 
     135      EventMachine.start_server( TestHost, TestPort, LineAndTextTest ) do |conn| 
     136        conn.instance_eval "@lines = lines_received; @text = text_received" 
     137      end 
     138      EventMachine.add_timer(4) {assert(false, "test timed out")} 
    186139 
    187     #-------------------------------------------------------------------- 
    188 end 
     140      EventMachine.connect TestHost, TestPort, StopClient do |c| 
     141        c.set_receive_data { |data| output << data } 
     142        c.send_data "Content-length: 400\n" 
     143        c.send_data "\n" 
     144        c.send_data "A" * 400 
     145        EM.add_timer(0.1) { c.close_connection_after_writing } 
     146      end 
     147    } 
     148    assert_equal( "received 400 bytes", output ) 
     149  end 
     150 
     151  #-------------------------------------------------------------------- 
    189152 
    190153 
     154  class BinaryTextTest < EventMachine::Protocols::LineAndTextProtocol 
     155    def post_init 
     156    end 
     157    def receive_line line 
     158      if line =~ /content-length:\s*(\d+)/i 
     159        set_binary_mode $1.to_i 
     160      else 
     161        raise "protocol error" 
     162      end 
     163    end 
     164    def receive_binary_data text 
     165      send_data "received #{text.length} bytes" 
     166      close_connection_after_writing 
     167    end 
     168  end 
     169 
     170  def test_binary_text 
     171    output = '' 
     172    lines_received = [] 
     173    text_received = [] 
     174    Thread.abort_on_exception = true 
     175    EventMachine.run { 
     176      EventMachine.start_server( TestHost, TestPort, BinaryTextTest ) do |conn| 
     177        conn.instance_eval "@lines = lines_received; @text = text_received" 
     178      end 
     179      EventMachine.add_timer(4) {assert(false, "test timed out")} 
     180 
     181      EventMachine.connect TestHost, TestPort, StopClient do |c| 
     182        c.set_receive_data { |data| output << data } 
     183        c.send_data "Content-length: 10000\n" 
     184        c.send_data "A" * 10000 
     185        EM.add_timer(0.2) { c.close_connection_after_writing } 
     186      end 
     187    } 
     188    assert_equal( "received 10000 bytes", output ) 
     189  end 
     190 
     191  #-------------------------------------------------------------------- 
     192end 
  • trunk/tests/test_pure.rb

    r668 r788  
    6868  end 
    6969  def test_exception_2 
    70     assert_raise( RuntimeError ) { run_exception } 
     70                ex_class = RUBY_PLATFORM == 'java' ? NativeException : RuntimeError 
     71    assert_raise( ex_class ) { run_exception } 
    7172  end 
    7273 
  • trunk/tests/test_send_file.rb

    r668 r788  
    3838                end 
    3939        end 
     40         
     41        module TestClient 
     42          def data_to(&blk) 
     43            @data_to = blk 
     44    end 
     45     
     46    def receive_data(data) 
     47      @data_to.call(data) if @data_to 
     48    end 
     49     
     50    def unbind 
     51      EM.stop 
     52    end 
     53  end 
    4054 
    4155        TestHost = "0.0.0.0" 
     
    5569                } 
    5670 
    57                 data = nil 
     71                data = '' 
    5872 
    5973                EM.run { 
    6074                        EM.start_server TestHost, TestPort, TestModule 
    6175                        EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    62                         EM.defer proc { 
    63                                 t = TCPSocket.new TestHost, TestPort 
    64                                 data = t.read 
    65                         }, proc { 
    66                                 EM.stop 
    67                         } 
     76                         
     77                        EM.connect TestHost, TestPort, TestClient do |c| 
     78                          c.data_to { |d| data << d } 
     79                  end 
    6880                } 
    6981 
     
    7890                } 
    7991 
    80                 data = nil 
    81  
    82                 assert_raise(RuntimeError) { 
     92                data = '' 
     93 
     94                ex_class = RUBY_PLATFORM == 'java' ? NativeException : RuntimeError 
     95    assert_raise( ex_class ) { 
    8396                        EM.run { 
    8497                                EM.start_server TestHost, TestPort, TestModule 
    8598                                EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    86                                 EM.defer proc { 
    87                                         t = TCPSocket.new TestHost, TestPort 
    88                                         data = t.read 
    89                                 }, proc { 
    90                                         EM.stop 
    91                                 } 
     99                        EM.connect TestHost, TestPort, TestClient do |c| 
     100                          c.data_to { |d| data << d } 
     101                  end 
    92102                        } 
    93103                } 
     
    118128                } 
    119129 
    120                 data = nil 
     130                data = '' 
    121131 
    122132                EM.run { 
    123133                        EM.start_server TestHost, TestPort, StreamTestModule 
    124134                        EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    125                         EM.defer proc { 
    126                                 t = TCPSocket.new TestHost, TestPort 
    127                                 data = t.read 
    128                         }, proc { 
    129                                 EM.stop 
    130                         } 
     135                        EM.connect TestHost, TestPort, TestClient do |c| 
     136                          c.data_to { |d| data << d } 
     137                  end 
    131138                } 
    132139 
     
    141148                } 
    142149 
    143                 data = nil 
     150                data = '' 
    144151 
    145152                EM.run { 
    146153                        EM.start_server TestHost, TestPort, ChunkStreamTestModule 
    147154                        EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    148                         EM.defer proc { 
    149                                 t = TCPSocket.new TestHost, TestPort 
    150                                 data = t.read 
    151                         }, proc { 
    152                                 EM.stop 
    153                         } 
     155                        EM.connect TestHost, TestPort, TestClient do |c| 
     156                          c.data_to { |d| data << d } 
     157                  end 
    154158                } 
    155159 
     
    169173        end 
    170174        def test_stream_bad_file 
    171                 data = nil 
     175                data = '' 
    172176                EM.run { 
    173177                        EM.start_server TestHost, TestPort, BadFileTestModule 
    174178                        EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    175                         EM.defer proc { 
    176                                 t = TCPSocket.new TestHost, TestPort 
    177                                 data = t.read 
    178                         }, proc { 
    179                                 EM.stop 
    180                         } 
     179                        EM.connect TestHost, TestPort, TestClient do |c| 
     180                          c.data_to { |d| data << d } 
     181                  end 
    181182                } 
    182183 
     
    189190                } 
    190191 
    191                 data = nil 
     192                data = '' 
    192193 
    193194                EM.run { 
    194195                        EM.start_server TestHost, TestPort, StreamTestModule 
    195196                        EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    196                         EM.defer proc { 
    197                                 t = TCPSocket.new TestHost, TestPort 
    198                                 data = t.read 
    199                         }, proc { 
    200                                 EM.stop 
    201                         } 
     197                        EM.connect TestHost, TestPort, TestClient do |c| 
     198                          c.data_to { |d| data << d } 
     199                  end 
    202200                } 
    203201 
     
    212210                } 
    213211 
    214                 data = nil 
     212                data = '' 
    215213 
    216214                EM.run { 
    217215                        EM.start_server TestHost, TestPort, ChunkStreamTestModule 
    218216                        EM.add_timer(2) {EM.stop} # avoid hanging in case of error 
    219                         EM.defer proc { 
    220                                 t = TCPSocket.new TestHost, TestPort 
    221                                 data = t.read 
    222                         }, proc { 
    223                                 EM.stop 
    224                         } 
     217                        EM.connect TestHost, TestPort, TestClient do |c| 
     218                          c.data_to { |d| data << d } 
     219                  end 
    225220                } 
    226221 
  • trunk/tests/test_servers.rb

    r668 r788  
    3434 
    3535        Host = "127.0.0.1" 
    36         Port = 9550 
    37  
    38         def setup 
    39         end 
    40  
    41         def teardown 
    42         end 
    43  
     36        Port = 9555 
     37         
     38        module NetstatHelper 
     39          GlobalUdp4Rexp = /udp.*\s+(?:\*|(?:0\.){3}0)[:.](\d+)\s/i 
     40          GlobalTcp4Rexp = /tcp.*\s+(?:\*|(?:0\.){3}0)[:.](\d+)\s/i 
     41          LocalUdpRexp = /udp.*\s+(?:127\.0\.0\.1|::1)[:.](\d+)\s/i 
     42          LocalTcpRexp = /tcp.*\s+(?:127\.0\.0\.1|::1)[:.](\d+)\s/i 
     43          def grep_netstat(pattern) 
     44            `netstat -an`.grep(pattern) 
     45    end 
     46  end 
     47        include NetstatHelper 
    4448 
    4549        class TestStopServer < EM::Connection 
     
    5256                end 
    5357        end 
     58         
    5459        def run_test_stop_server 
    55                 succeed = false 
    56                 err = false 
    57                 EM.run { 
    58                         sig = EM.start_server(Host, Port) 
    59                         EM.defer proc { 
    60                                 if TCPSocket.new Host, Port 
    61                                         succeed = true 
    62                                 end 
    63                         }, proc { 
    64                                 EM.stop_server sig 
    65                                 EM.defer proc { 
    66                                         # Wait for the acceptor to die, otherwise 
    67                                         # we'll probably get a conn-reset instead 
    68                                         # of a conn-refused. 
    69                                         sleep 0.1 
    70                                         begin 
    71                                                 TCPSocket.new Host, Port 
    72                                         rescue 
    73                                                 err = $! 
    74                                         end 
    75                                 }, proc { 
    76                                         EM.stop 
    77                                 } 
    78                         } 
    79                 } 
    80                 assert_equal( true, succeed ) 
    81                 assert_equal( Errno::ECONNREFUSED, err.class ) 
     60          EM.run { 
     61            sig = EM.start_server(Host, Port) 
     62            assert(grep_netstat(LocalTcpRexp).grep(%r(#{Port})).size >= 1, "Server didn't start") 
     63            EM.stop_server sig 
     64            # Give the server some time to shutdown. 
     65            EM.add_timer(0.1) { 
     66                assert(grep_netstat(LocalTcpRexp).grep(%r(#{Port})).empty?, "Servers didn't stop")           
     67            EM.stop 
     68            } 
     69          } 
    8270        end 
    8371        def test_stop_server 
     72          assert(grep_netstat(LocalTcpRexp).grep(Port).empty?, "Port already in use") 
    8473                5.times {run_test_stop_server} 
     74                assert(grep_netstat(LocalTcpRexp).grep(%r(#{Port})).empty?, "Servers didn't stop") 
    8575        end 
    8676 
  • trunk/tests/test_timers.rb

    r715 r788  
    7474          x = 0 
    7575          EventMachine.run { 
    76                   EventMachine::PeriodicTimer.new(0.1, proc { 
     76                  EventMachine::PeriodicTimer.new(0.1) do 
    7777                        x += 1 
    78                         EventMachine.stop if x == 4 
    79                  }) 
     78                          EventMachine.stop if x == 4 
     79            end 
    8080          } 
    8181          assert( x == 4 ) 
     
    8585          x = 0 
    8686          EventMachine.run { 
    87                 pt = EventMachine::PeriodicTimer.new(5, proc { x += 1 }) 
     87                pt = EventMachine::PeriodicTimer.new(0.25, proc { x += 1 }) 
    8888                pt.cancel 
    8989                EventMachine::Timer.new(0.5) {EventMachine.stop} 
     
    122122                                ten_thousand_timers.call 
    123123                        else 
    124                                 assert_raise( RuntimeError ) { 
    125                                         ten_thousand_timers.call 
    126                                 } 
     124                          begin 
     125                                assert_raise( RuntimeError ) { 
     126                                        ten_thousand_timers.call 
     127                                } 
     128                        rescue Object 
     129                          p $! 
     130                          assert(false, $!.message) 
     131                  end 
    127132                        end 
    128133                        EM.stop 
    129134                } 
    130135 
    131                 EM.set_max_timers( 10001 ) 
     136    assert(!EM.reactor_running?, 'Reactor running when it should not be.') 
     137    EM.set_max_timers( 10001 ) 
    132138 
    133139                EM.run {