eventmachine-le 1.1.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. data/.gitignore +21 -0
  2. data/.yardopts +7 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +80 -0
  6. data/Rakefile +19 -0
  7. data/eventmachine-le.gemspec +42 -0
  8. data/ext/binder.cpp +124 -0
  9. data/ext/binder.h +46 -0
  10. data/ext/cmain.cpp +841 -0
  11. data/ext/ed.cpp +1995 -0
  12. data/ext/ed.h +424 -0
  13. data/ext/em.cpp +2377 -0
  14. data/ext/em.h +243 -0
  15. data/ext/eventmachine.h +126 -0
  16. data/ext/extconf.rb +166 -0
  17. data/ext/fastfilereader/extconf.rb +94 -0
  18. data/ext/fastfilereader/mapper.cpp +214 -0
  19. data/ext/fastfilereader/mapper.h +59 -0
  20. data/ext/fastfilereader/rubymain.cpp +127 -0
  21. data/ext/kb.cpp +79 -0
  22. data/ext/page.cpp +107 -0
  23. data/ext/page.h +51 -0
  24. data/ext/pipe.cpp +347 -0
  25. data/ext/project.h +155 -0
  26. data/ext/rubymain.cpp +1269 -0
  27. data/ext/ssl.cpp +468 -0
  28. data/ext/ssl.h +94 -0
  29. data/lib/em/buftok.rb +110 -0
  30. data/lib/em/callback.rb +58 -0
  31. data/lib/em/channel.rb +64 -0
  32. data/lib/em/completion.rb +304 -0
  33. data/lib/em/connection.rb +728 -0
  34. data/lib/em/deferrable.rb +210 -0
  35. data/lib/em/deferrable/pool.rb +2 -0
  36. data/lib/em/file_watch.rb +73 -0
  37. data/lib/em/future.rb +61 -0
  38. data/lib/em/iterator.rb +313 -0
  39. data/lib/em/messages.rb +66 -0
  40. data/lib/em/pool.rb +151 -0
  41. data/lib/em/process_watch.rb +45 -0
  42. data/lib/em/processes.rb +123 -0
  43. data/lib/em/protocols.rb +37 -0
  44. data/lib/em/protocols/header_and_content.rb +138 -0
  45. data/lib/em/protocols/httpclient.rb +279 -0
  46. data/lib/em/protocols/httpclient2.rb +600 -0
  47. data/lib/em/protocols/line_and_text.rb +125 -0
  48. data/lib/em/protocols/line_protocol.rb +29 -0
  49. data/lib/em/protocols/linetext2.rb +161 -0
  50. data/lib/em/protocols/memcache.rb +331 -0
  51. data/lib/em/protocols/object_protocol.rb +46 -0
  52. data/lib/em/protocols/postgres3.rb +246 -0
  53. data/lib/em/protocols/saslauth.rb +175 -0
  54. data/lib/em/protocols/smtpclient.rb +365 -0
  55. data/lib/em/protocols/smtpserver.rb +663 -0
  56. data/lib/em/protocols/socks4.rb +66 -0
  57. data/lib/em/protocols/stomp.rb +202 -0
  58. data/lib/em/protocols/tcptest.rb +54 -0
  59. data/lib/em/queue.rb +71 -0
  60. data/lib/em/resolver.rb +195 -0
  61. data/lib/em/spawnable.rb +84 -0
  62. data/lib/em/streamer.rb +118 -0
  63. data/lib/em/threaded_resource.rb +90 -0
  64. data/lib/em/tick_loop.rb +85 -0
  65. data/lib/em/timers.rb +106 -0
  66. data/lib/em/version.rb +3 -0
  67. data/lib/eventmachine-le.rb +10 -0
  68. data/lib/eventmachine.rb +1548 -0
  69. data/rakelib/cpp.rake_example +77 -0
  70. data/rakelib/package.rake +98 -0
  71. data/rakelib/test.rake +8 -0
  72. data/tests/client.crt +31 -0
  73. data/tests/client.key +51 -0
  74. data/tests/em_test_helper.rb +143 -0
  75. data/tests/test_attach.rb +148 -0
  76. data/tests/test_basic.rb +294 -0
  77. data/tests/test_channel.rb +62 -0
  78. data/tests/test_completion.rb +177 -0
  79. data/tests/test_connection_count.rb +33 -0
  80. data/tests/test_defer.rb +18 -0
  81. data/tests/test_deferrable.rb +35 -0
  82. data/tests/test_epoll.rb +134 -0
  83. data/tests/test_error_handler.rb +38 -0
  84. data/tests/test_exc.rb +28 -0
  85. data/tests/test_file_watch.rb +65 -0
  86. data/tests/test_futures.rb +170 -0
  87. data/tests/test_get_sock_opt.rb +37 -0
  88. data/tests/test_handler_check.rb +35 -0
  89. data/tests/test_hc.rb +155 -0
  90. data/tests/test_httpclient.rb +190 -0
  91. data/tests/test_httpclient2.rb +128 -0
  92. data/tests/test_inactivity_timeout.rb +54 -0
  93. data/tests/test_ipv4.rb +125 -0
  94. data/tests/test_ipv6.rb +131 -0
  95. data/tests/test_iterator.rb +110 -0
  96. data/tests/test_kb.rb +34 -0
  97. data/tests/test_line_protocol.rb +33 -0
  98. data/tests/test_ltp.rb +138 -0
  99. data/tests/test_ltp2.rb +288 -0
  100. data/tests/test_next_tick.rb +104 -0
  101. data/tests/test_object_protocol.rb +36 -0
  102. data/tests/test_pause.rb +78 -0
  103. data/tests/test_pending_connect_timeout.rb +52 -0
  104. data/tests/test_pool.rb +196 -0
  105. data/tests/test_process_watch.rb +48 -0
  106. data/tests/test_processes.rb +133 -0
  107. data/tests/test_proxy_connection.rb +168 -0
  108. data/tests/test_pure.rb +88 -0
  109. data/tests/test_queue.rb +50 -0
  110. data/tests/test_resolver.rb +55 -0
  111. data/tests/test_running.rb +14 -0
  112. data/tests/test_sasl.rb +47 -0
  113. data/tests/test_send_file.rb +217 -0
  114. data/tests/test_servers.rb +33 -0
  115. data/tests/test_set_sock_opt.rb +41 -0
  116. data/tests/test_shutdown_hooks.rb +23 -0
  117. data/tests/test_smtpclient.rb +55 -0
  118. data/tests/test_smtpserver.rb +120 -0
  119. data/tests/test_spawn.rb +293 -0
  120. data/tests/test_ssl_args.rb +78 -0
  121. data/tests/test_ssl_methods.rb +48 -0
  122. data/tests/test_ssl_verify.rb +82 -0
  123. data/tests/test_threaded_resource.rb +55 -0
  124. data/tests/test_tick_loop.rb +59 -0
  125. data/tests/test_timers.rb +180 -0
  126. data/tests/test_ud.rb +8 -0
  127. data/tests/test_udp46.rb +53 -0
  128. data/tests/test_unbind_reason.rb +48 -0
  129. metadata +390 -0
@@ -0,0 +1,77 @@
1
+ # EventMachine C++ Rakefile Stab Case
2
+ # TODO : track header files as a build dependency...
3
+ # TODO : cross platform support
4
+ # TODO : configure style functionality
5
+ namespace :cpp do
6
+
7
+ require 'rake/clean'
8
+
9
+ # *nix only atm...
10
+ module Cpp
11
+ class <<self
12
+ def cpp; "g++"; end
13
+ def archive; "ar"; end
14
+ def compile file, output, includes=nil, flags=nil
15
+ sh %{#{cpp} #{file} #{includes} #{flags} -c -o #{output}}
16
+ end
17
+ def link file, output, libs=nil, flags=nil
18
+ sh %{#{cpp} #{file} #{libs} #{flags} -o #{output}}
19
+ end
20
+ def static output, files
21
+ sh %{#{archive} cr #{output} #{files}}
22
+ end
23
+ end
24
+ end
25
+
26
+ module EmConfig
27
+ Path = ENV['EVENTMACHINE_SOURCE'] || 'ext'
28
+ Sources = FileList["#{Path}/*.cpp"]
29
+ Sources.delete_if { |s| /ruby/ =~ s }
30
+ Compiled = Sources.sub(%r{^#{Path}/(.*)\.cpp}, "#{Path}/\\1.o")
31
+
32
+ Flags = "-O2 -pipe -fno-common -DOS_UNIX -DWITHOUT_SSL"
33
+ Includes = ""
34
+ Libs = ''
35
+ end
36
+ CLEAN.include(EmConfig::Compiled)
37
+
38
+ rule %r{^#{EmConfig::Path}/.*\.o$} => [proc { |targ|
39
+ targ.sub(%r{^#{EmConfig::Path}/(.*)\.o$}, "#{EmConfig::Path}/\\1.cpp")
40
+ }] do |t|
41
+ Cpp.compile t.source, t.name, EmConfig::Includes, EmConfig::Flags
42
+ end
43
+
44
+ file "#{EmConfig::Path}/libeventmachine.a" => EmConfig::Compiled do |t|
45
+ Cpp.static t.name, EmConfig::Compiled
46
+ end
47
+ CLEAN.include("#{EmConfig::Path}/libeventmachine.a")
48
+
49
+ module AppConfig
50
+ Appname = 'echo_em'
51
+ Sources = FileList['*.cpp']
52
+ Compiled = Sources.sub(%r{^(.*)\.cpp}, '\\1.o')
53
+
54
+ Flags = ["", EmConfig::Flags].join(' ')
55
+ Includes = ["-I. -I#{EmConfig::Path}", EmConfig::Includes].join(' ')
56
+ Libs = ["-L#{EmConfig::Path} -leventmachine", EmConfig::Libs].join(' ')
57
+ end
58
+ CLEAN.include(AppConfig::Compiled)
59
+ CLEAN.include(AppConfig::Appname)
60
+
61
+ rule %r{^.*\.o$} => [proc { |targ|
62
+ targ.sub(%r{^(.*)\.o$}, '\\1.cpp')
63
+ }] do |t|
64
+ Cpp.compile t.source, t.name, AppConfig::Includes, AppConfig::Flags
65
+ end
66
+
67
+ file AppConfig::Appname => ["#{EmConfig::Path}/libeventmachine.a", AppConfig::Compiled] do |t|
68
+ Cpp.link AppConfig::Compiled, t.name, AppConfig::Libs, AppConfig::Flags
69
+ end
70
+
71
+ task :build => AppConfig::Appname
72
+
73
+ task :run => AppConfig::Appname do
74
+ sh "./#{AppConfig::Appname}"
75
+ end
76
+
77
+ end
@@ -0,0 +1,98 @@
1
+ require 'rubygems/package_task'
2
+ begin
3
+ require 'rake/extensiontask'
4
+ require 'rake/javaextensiontask'
5
+ rescue LoadError => e
6
+ puts <<-MSG
7
+ rake-compiler gem seems to be missing. Please install it with
8
+
9
+ gem install rake-compiler
10
+
11
+ (add sudo if necessary).
12
+ MSG
13
+ end
14
+
15
+ Gem::PackageTask.new(GEMSPEC) do |pkg|
16
+ end
17
+
18
+ if RUBY_PLATFORM =~ /java/
19
+ Rake::JavaExtensionTask.new("rubyeventmachine", GEMSPEC) do |ext|
20
+ ext.ext_dir = 'java/src'
21
+ end
22
+ else
23
+ def setup_cross_compilation(ext)
24
+ unless RUBY_PLATFORM =~ /mswin|mingw/
25
+ ext.cross_compile = true
26
+ ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60']
27
+
28
+ # inject 1.8/1.9 pure-ruby entry point
29
+ ext.cross_compiling do |spec|
30
+ spec.files += ["lib/#{ext.name}.rb"]
31
+ end
32
+ end
33
+ end
34
+
35
+ Rake::ExtensionTask.new("rubyeventmachine", GEMSPEC) do |ext|
36
+ ext.ext_dir = 'ext'
37
+ ext.source_pattern = '*.{h,c,cpp}'
38
+ setup_cross_compilation(ext)
39
+ end
40
+ Rake::ExtensionTask.new("fastfilereaderext", GEMSPEC) do |ext|
41
+ ext.ext_dir = 'ext/fastfilereader'
42
+ ext.source_pattern = '*.{h,c,cpp}'
43
+ setup_cross_compilation(ext)
44
+ end
45
+ end
46
+
47
+ # Setup shim files that require 1.8 vs 1.9 extensions in win32 bin gems
48
+ %w[ rubyeventmachine fastfilereaderext ].each do |filename|
49
+ file("lib/#{filename}.rb") do |t|
50
+ File.open(t.name, 'wb') do |f|
51
+ f.write <<-eoruby
52
+ RUBY_VERSION =~ /(\\d+.\\d+)/
53
+ require "\#{$1}/#{File.basename(t.name, '.rb')}"
54
+ eoruby
55
+ end
56
+ at_exit{ FileUtils.rm t.name if File.exists?(t.name) }
57
+ end
58
+ end
59
+
60
+ task :cross_cxx do
61
+ ENV['CROSS_COMPILING'] = 'yes'
62
+ require 'rake/extensioncompiler'
63
+ ENV['CXX'] = "#{Rake::ExtensionCompiler.mingw_host}-g++"
64
+ end
65
+
66
+ if Rake::Task.task_defined?(:cross)
67
+ task :cross => 'lib/rubyeventmachine.rb'
68
+ task :cross => 'lib/fastfilereaderext.rb'
69
+ task :cross => :cross_cxx
70
+ end
71
+
72
+ def windows?; RUBY_PLATFORM =~ /mswin|mingw/; end
73
+ def sudo(cmd)
74
+ if windows? || (require 'etc'; Etc.getpwuid.uid == 0)
75
+ sh cmd
76
+ else
77
+ sh "sudo #{cmd}"
78
+ end
79
+ end
80
+ def gem_cmd(action, name, *args)
81
+ rb = Gem.ruby rescue nil
82
+ rb ||= (require 'rbconfig'; File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']))
83
+ sudo "#{rb} -r rubygems -e 'require %{rubygems/gem_runner}; Gem::GemRunner.new.run(%w{#{action} #{name} #{args.join(' ')}})'"
84
+ end
85
+
86
+ Rake::Task[:clean].enhance [:clobber_package]
87
+
88
+ namespace :gem do
89
+ desc 'Install gem (and sudo if required)'
90
+ task :install => :package do
91
+ gem_cmd(:install, "pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem")
92
+ end
93
+
94
+ desc 'Uninstall gem (and sudo if required)'
95
+ task :uninstall do
96
+ gem_cmd(:uninstall, "#{GEMSPEC.name}", "-v=#{GEMSPEC.version}")
97
+ end
98
+ end
data/rakelib/test.rake ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new(:test) do |t|
4
+ t.libs << "tests"
5
+ t.libs << "lib"
6
+ t.pattern = 'tests/**/test_*.rb'
7
+ t.warning = true
8
+ end
data/tests/client.crt ADDED
@@ -0,0 +1,31 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFRDCCAywCAQEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCRU0xFTATBgNV
3
+ BAgTDEV2ZW50TWFjaGluZTEVMBMGA1UEChMMRXZlbnRNYWNoaW5lMRQwEgYDVQQL
4
+ EwtEZXZlbG9wbWVudDEVMBMGA1UEAxMMRXZlbnRNYWNoaW5lMB4XDTA5MDMyOTAy
5
+ MzE0NloXDTEwMDMyOTAyMzE0NlowaDELMAkGA1UEBhMCRU0xFTATBgNVBAgTDEV2
6
+ ZW50TWFjaGluZTEVMBMGA1UEChMMRXZlbnRNYWNoaW5lMRQwEgYDVQQLEwtEZXZl
7
+ bG9wbWVudDEVMBMGA1UEAxMMRXZlbnRNYWNoaW5lMIICIjANBgkqhkiG9w0BAQEF
8
+ AAOCAg8AMIICCgKCAgEAv1FSOIX1z7CQtVBFlrB0A3/V29T+22STKKmiRWYkKL5b
9
+ +hkrp9IZ5J4phZHgUVM2VDPOO2Oc2PU6dlGGZISg+UPERunTogxQKezCV0vcE9cK
10
+ OwzxCFDRvv5rK8aKMscfBLbNKocAXywuRRQmdxPiVRzbyPrl+qCr/EDLXAX3D77l
11
+ S8n2AwDg19VyI+IgFUE+Dy5e1eLoY6nV+Mq+vNXdn3ttF3t+ngac5pj5Q9h+pD5p
12
+ 67baDHSnf/7cy2fa/LKrLolVHQR9G2K6cEfeM99NtcsMbkoPs4iI3FA05OVTQHXg
13
+ C8C8cRxrb9APl95I/ep65OIaCJgcdYxJ3QD3qOtQo6/NQsGnjbyiUxaEpjfqyT1N
14
+ uzWD81Q8uXGNS8yD6dDynt/lseBjyp2nfC3uQ5fY18VdIcu0MJ9pezBUKrNuhlsy
15
+ XXEZ2DXj4sY8QOvIcBqSB/zmS1nGEK55xrtkaiaNrY8fe8wRVpcPLxy+P225NFw+
16
+ B69FJRA0Lj6Jt9BM4hV/3MSIEWwTVhuw4E02ywDYTzz1wq3ITf0tsbIPn0hXQMxD
17
+ ohhAoKioM6u+yHtqsxD0eYaAWmHTVn5oDvOSGpvCpBfWHyA7FP5UQak0fKABEAgK
18
+ iQYEnb294AXwXymJttfGTIV/Ne4tLN5dIpNma8UO8rlThlcr6xnTQDbR3gkTDRsC
19
+ AwEAATANBgkqhkiG9w0BAQUFAAOCAgEAj7J8fy1LUWoVWnrXDAC9jwJ1nI/YjoSU
20
+ 6ywke3o04+nZC5S+dPnuVy+HAwsU940CoNvP6RStI/bH6JL+NIqEFmwM3M8xIEWV
21
+ MYVPkfvQUxxGvDnaY7vv93u+6Q77HV3qlhAQBHChyuXyO7TG3+WzsiT9AnBNtAP0
22
+ 4jClt5kCAQXLO/p0SFEZQ8Ru9SM8d1i73Z0VDVzs8jYWlBhiherSgbw1xK4wBOpJ
23
+ 43XmjZsBSrDpiAXd07Ak3UL2GjfT7eStgebL3UIe39ThE/s/+l43bh0M6WbOBvyQ
24
+ i/rZ50kd1GvN0xnZhtv07hIJWO85FGWi7Oet8AzdUZJ17v1Md/f2vdhPVTFN9q+w
25
+ mQ6LxjackqCvaJaQfBEbqsn2Tklxk4tZuDioiQbOElT2e6vljQVJWIfNx38Ny2LM
26
+ aiXQPQu+4CI7meAh5gXM5nyJGbZvRPsxj89CqYzyHCYs5HBP3AsviBvn26ziOF+c
27
+ 544VmHd9HkIv8UTC29hh+R64RlgMQQQdaXFaUrFPTs/do0k8n/c2bPc0iTdfi5Q2
28
+ gq6Vi8q6Ay5wGgTtRRbn/mWKuCFjEh94z6pF9Xr06NX0PuEOdf+Ls9vI5vz6G0w6
29
+ 0Li7devEN7EKBY+7Mcjg918yq9i5tEiMkUgT68788t3fTC+4iUQ5fDtdrHsaOlIR
30
+ 8bs/XQVNE/s=
31
+ -----END CERTIFICATE-----
data/tests/client.key ADDED
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,143 @@
1
+ require 'eventmachine'
2
+ require 'test/unit'
3
+ require 'rbconfig'
4
+ require 'socket'
5
+
6
+ class Test::Unit::TestCase
7
+ class EMTestTimeout < StandardError ; end
8
+
9
+ def setup_timeout(timeout = TIMEOUT_INTERVAL)
10
+ EM.schedule {
11
+ EM.add_timer(timeout) {
12
+ raise EMTestTimeout, "Test was cancelled after #{timeout} seconds."
13
+ }
14
+ }
15
+ end
16
+
17
+ def port_in_use?(port, host="127.0.0.1")
18
+ s = TCPSocket.new(host, port)
19
+ s.close
20
+ s
21
+ rescue Errno::ECONNREFUSED
22
+ false
23
+ end
24
+
25
+ def next_port
26
+ @@port ||= 9000
27
+ begin
28
+ @@port += 1
29
+ end while port_in_use?(@@port)
30
+
31
+ @@port
32
+ end
33
+
34
+ # Returns true if the host have a localhost 127.0.0.1 IPv6.
35
+ def self.local_ipv4?
36
+ return @@has_local_ipv4 if defined?(@@has_local_ipv4)
37
+ begin
38
+ get_my_ipv4_address "127.0.0.1"
39
+ @@has_local_ipv4 = true
40
+ rescue
41
+ @@has_local_ipv4 = false
42
+ end
43
+ end
44
+
45
+ # Returns true if the host have a public IPv6 and stores it in
46
+ # @@public_ipv4.
47
+ def self.public_ipv4?
48
+ return @@has_public_ipv4 if defined?(@@has_public_ipv4)
49
+ begin
50
+ @@public_ipv4 = get_my_ipv4_address "1.2.3.4"
51
+ @@has_public_ipv4 = true
52
+ rescue
53
+ @@has_public_ipv4 = false
54
+ end
55
+ end
56
+
57
+ # Returns true if the host have a localhost ::1 IPv6.
58
+ def self.local_ipv6?
59
+ return @@has_local_ipv6 if defined?(@@has_local_ipv6)
60
+ begin
61
+ get_my_ipv6_address "::1"
62
+ @@has_local_ipv6 = true
63
+ rescue
64
+ @@has_local_ipv6 = false
65
+ end
66
+ end
67
+
68
+ # Returns true if the host have a public IPv6 and stores it in
69
+ # @@public_ipv6.
70
+ def self.public_ipv6?
71
+ return @@has_public_ipv6 if defined?(@@has_public_ipv6)
72
+ begin
73
+ @@public_ipv6 = get_my_ipv6_address "2001::1"
74
+ @@has_public_ipv6 = true
75
+ rescue
76
+ @@has_public_ipv6 = false
77
+ end
78
+ end
79
+
80
+ # Returns an array with the localhost addresses (IPv4 and/or IPv6).
81
+ def local_ips
82
+ return @@local_ips if defined?(@@local_ips)
83
+ @@local_ips = []
84
+ @@local_ips << "127.0.0.1" if self.class.local_ipv4?
85
+ @@local_ips << "::1" if self.class.local_ipv6?
86
+ @@local_ips
87
+ end
88
+
89
+ def exception_class
90
+ jruby? ? NativeException : RuntimeError
91
+ end
92
+
93
+ module PlatformHelper
94
+ # http://blog.emptyway.com/2009/11/03/proper-way-to-detect-windows-platform-in-ruby/
95
+ def windows?
96
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
97
+ end
98
+
99
+ # http://stackoverflow.com/questions/1342535/how-can-i-tell-if-im-running-from-jruby-vs-ruby/1685970#1685970
100
+ def jruby?
101
+ defined? JRUBY_VERSION
102
+ end
103
+ end
104
+
105
+ include PlatformHelper
106
+ extend PlatformHelper
107
+
108
+ # Tests run significantly slower on windows. YMMV
109
+ TIMEOUT_INTERVAL = windows? ? 1 : 0.25
110
+
111
+ def silent
112
+ backup, $VERBOSE = $VERBOSE, nil
113
+ begin
114
+ yield
115
+ ensure
116
+ $VERBOSE = backup
117
+ end
118
+ end
119
+
120
+
121
+ private
122
+
123
+ def self.get_my_ipv4_address ip
124
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
125
+ UDPSocket.open(Socket::AF_INET) do |s|
126
+ s.connect ip, 1
127
+ s.addr.last
128
+ end
129
+ ensure
130
+ Socket.do_not_reverse_lookup = orig
131
+ end
132
+
133
+ def self.get_my_ipv6_address ip
134
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
135
+ UDPSocket.open(Socket::AF_INET6) do |s|
136
+ s.connect ip, 1
137
+ s.addr.last
138
+ end
139
+ ensure
140
+ Socket.do_not_reverse_lookup = orig
141
+ end
142
+
143
+ end
@@ -0,0 +1,148 @@
1
+ require 'em_test_helper'
2
+ require 'socket'
3
+
4
+ class TestAttach < Test::Unit::TestCase
5
+ class EchoServer < EM::Connection
6
+ def receive_data data
7
+ $received_data << data
8
+ send_data data
9
+ end
10
+ end
11
+
12
+ class EchoClient < EM::Connection
13
+ def initialize socket
14
+ self.notify_readable = true
15
+ @socket = socket
16
+ @socket.write("abc\n")
17
+ end
18
+
19
+ def notify_readable
20
+ $read = @socket.readline
21
+ $fd = detach
22
+ end
23
+
24
+ def unbind
25
+ EM.next_tick do
26
+ @socket.write("def\n")
27
+ EM.add_timer(0.1) { EM.stop }
28
+ end
29
+ end
30
+ end
31
+
32
+ def setup
33
+ @port = next_port
34
+ $read, $r, $w, $fd = nil
35
+ $received_data = ""
36
+ end
37
+
38
+ def teardown
39
+ [$r, $w].each do |io|
40
+ io.close rescue nil
41
+ end
42
+ $received_data = nil
43
+ end
44
+
45
+ def test_attach
46
+ socket = nil
47
+
48
+ EM.run {
49
+ EM.start_server "127.0.0.1", @port, EchoServer
50
+ socket = TCPSocket.new "127.0.0.1", @port
51
+ EM.watch socket, EchoClient, socket
52
+ }
53
+
54
+ assert_equal $read, "abc\n"
55
+ unless jruby? # jruby filenos are not real
56
+ assert_equal $fd, socket.fileno
57
+ end
58
+ assert_equal false, socket.closed?
59
+ assert_equal socket.readline, "def\n"
60
+ end
61
+
62
+ def test_attach_server
63
+ $before = TCPServer.new("127.0.0.1", @port)
64
+ EM.run {
65
+ EM.attach_server $before, EchoServer
66
+
67
+ handler = Class.new(EM::Connection) do
68
+ def initialize
69
+ send_data "hello world"
70
+ close_connection_after_writing
71
+ EM.add_timer(0.1) { EM.stop }
72
+ end
73
+ end
74
+ EM.connect("127.0.0.1", @port, handler)
75
+ }
76
+
77
+ assert_equal false, $before.closed?
78
+ assert_equal "hello world", $received_data
79
+ end
80
+
81
+ module PipeWatch
82
+ def notify_readable
83
+ $read = $r.readline
84
+ EM.stop
85
+ end
86
+ end
87
+
88
+ def test_attach_pipe
89
+ EM.run{
90
+ $r, $w = IO.pipe
91
+ EM.watch $r, PipeWatch do |c|
92
+ c.notify_readable = true
93
+ end
94
+ $w.write("ghi\n")
95
+ }
96
+
97
+ assert_equal $read, "ghi\n"
98
+ end
99
+
100
+ def test_set_readable
101
+ before, after = nil
102
+
103
+ EM.run{
104
+ $r, $w = IO.pipe
105
+ c = EM.watch $r, PipeWatch do |con|
106
+ con.notify_readable = false
107
+ end
108
+
109
+ EM.next_tick{
110
+ before = c.notify_readable?
111
+ c.notify_readable = true
112
+ after = c.notify_readable?
113
+ }
114
+
115
+ $w.write("jkl\n")
116
+ }
117
+
118
+ assert !before
119
+ assert after
120
+ assert_equal $read, "jkl\n"
121
+ end
122
+
123
+ def test_read_write_pipe
124
+ result = nil
125
+
126
+ pipe_reader = Module.new do
127
+ define_method :receive_data do |data|
128
+ result = data
129
+ EM.stop
130
+ end
131
+ end
132
+
133
+ r,w = IO.pipe
134
+
135
+ EM.run {
136
+ EM.attach r, pipe_reader
137
+ writer = EM.attach(w)
138
+ writer.send_data 'ghi'
139
+
140
+ # XXX: Process will hang in Windows without this line
141
+ writer.close_connection_after_writing
142
+ }
143
+
144
+ assert_equal "ghi", result
145
+ ensure
146
+ [r,w].each {|io| io.close rescue nil }
147
+ end
148
+ end