remailer 0.5.2 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'eventmachine'
4
+ require 'optparse'
5
+ require 'securerandom'
6
+
7
+ $LOAD_PATH << File.expand_path('../../lib', File.dirname(__FILE__))
8
+
9
+ require 'remailer'
10
+
11
+ # == Support Methods ========================================================
12
+
13
+ class Exerciser
14
+ attr_reader :report
15
+
16
+ def initialize(options)
17
+ @options = options
18
+ @pending = [ ]
19
+ @report = { }
20
+ end
21
+
22
+ def test(server)
23
+ results = @report[server] = {
24
+ success: 0,
25
+ timeout: 0,
26
+ error: 0
27
+ }
28
+
29
+ @options[:count].times do
30
+ uuid = SecureRandom.uuid
31
+
32
+ @pending << uuid
33
+
34
+ connection_options = {
35
+ close: true,
36
+ proxy: {
37
+ host: @options[:proxy_host],
38
+ port: @options[:proxy_port]
39
+ },
40
+ connect: lambda do |success, host|
41
+ results[success ? :success : :error] += 1
42
+ @pending.delete(uuid)
43
+ end
44
+ }
45
+
46
+ if (@options[:verbose])
47
+ connection_options[:debug] = STDOUT
48
+ end
49
+
50
+ Remailer::SMTP::Client.open(server, connection_options)
51
+ end
52
+ end
53
+
54
+ def done?
55
+ @pending.empty?
56
+ end
57
+ end
58
+
59
+ # == Main ===================================================================
60
+
61
+ options = {
62
+ count: 1,
63
+ concurrency: 1,
64
+ proxy_host: 'localhost',
65
+ proxy_port: 1080
66
+ }
67
+
68
+ opts = OptionParser.new do |parser|
69
+ parser.banner = "Usage: exerciser [options] server [server [...]]"
70
+ parser.on('-n', '--count=n') do |n|
71
+ options[:count] = n.to_i
72
+ end
73
+ parser.on('-c', '--concurrency=n') do |n|
74
+ options[:concurrency] = n.to_i
75
+ end
76
+ parser.on('-X', '--proxy=s') do |s|
77
+ server, port = s.split(/:/)
78
+
79
+ options[:proxy_host] = server
80
+
81
+ if (port)
82
+ options[:proxy_port] = port.to_i
83
+ end
84
+ end
85
+ parser.on('-v', '--verbose') do
86
+ options[:verbose] = true
87
+ end
88
+ end
89
+
90
+ servers = opts.parse(*ARGV)
91
+
92
+ unless (servers.any?)
93
+ puts opts
94
+ exit(0)
95
+ end
96
+
97
+ EventMachine.run do
98
+ exerciser = Exerciser.new(options)
99
+
100
+ servers.each do |server|
101
+ exerciser.test(server)
102
+ end
103
+
104
+ EventMachine.add_periodic_timer(0.1) do
105
+ if (exerciser.done?)
106
+ puts '%-40s %-6s %-6s' % [ 'Server', 'Success', 'Fail' ]
107
+ puts '-' * 58
108
+ exerciser.report.each do |server, results|
109
+ puts '%-40s %6d %6d' % [ server, results[:success], results[:error] ]
110
+ end
111
+
112
+ EventMachine.stop_event_loop
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,15 @@
1
+ smtp_server:
2
+ host: "smtp.gmail.com"
3
+ identifier: "smtp.gmail.com"
4
+
5
+ public_smtp_server:
6
+ host: "smtp.gmail.com"
7
+ identifier: "mx.google.com"
8
+ username: "<account>@gmail.com"
9
+ password: "<password>"
10
+ port: 587
11
+
12
+ proxy_server: "<proxy.server>"
13
+
14
+ recipient: "<account>@gmail.com"
15
+ sender: "<account>@gmail.com"
@@ -0,0 +1,41 @@
1
+ require 'yaml'
2
+
3
+ class TestConfig < Hash
4
+ CONFIG_FILE = 'config.yml'
5
+
6
+ def self.options
7
+ @options ||= begin
8
+ config_path = File.expand_path(CONFIG_FILE, File.dirname(__FILE__))
9
+
10
+ unless (File.exist?(config_path))
11
+ raise "Config #{CONFIG_FILE} not found. Copy test/config.example.yml and fill in appropriate test settings."
12
+ end
13
+
14
+ new(config_path)
15
+ end
16
+ end
17
+
18
+ def initialize(path)
19
+ merge!(symbolized_keys(YAML.load(File.open(path))))
20
+ end
21
+
22
+ def symbolized_keys(object)
23
+ case (object)
24
+ when Hash
25
+ Hash[
26
+ object.collect do |key, value|
27
+ [
28
+ key ? key.to_sym : key,
29
+ symbolized_keys(value)
30
+ ]
31
+ end
32
+ ]
33
+ when Array
34
+ object.collect do |value|
35
+ symbolized_keys(value)
36
+ end
37
+ else
38
+ object
39
+ end
40
+ end
41
+ end
@@ -1,11 +1,15 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
2
+
3
+ gem 'minitest'
4
+ require 'minitest/autorun'
5
+ require 'minitest/reporters'
6
+
7
+ Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new)
3
8
 
4
9
  $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
5
10
  $LOAD_PATH.unshift(File.dirname(__FILE__))
6
11
 
7
12
  require 'timeout'
8
- require 'thwait'
9
13
  require 'rubygems'
10
14
 
11
15
  begin
@@ -14,8 +18,6 @@ rescue => e
14
18
  raise "EventMachine gem could not be loaded: #{e.class}: #{e}"
15
19
  end
16
20
 
17
- puts $LOAD_PATH.inspect
18
-
19
21
  require 'remailer'
20
22
 
21
23
  class Proc
@@ -38,8 +40,6 @@ end
38
40
  module TestTriggerHelper
39
41
  def self.included(base)
40
42
  base.class_eval do
41
- attr_reader :triggered
42
-
43
43
  def triggered
44
44
  @triggered ||= Hash.new(false)
45
45
  end
@@ -51,36 +51,64 @@ module TestTriggerHelper
51
51
  end
52
52
  end
53
53
 
54
- class Test::Unit::TestCase
54
+ if (ENV['DEBUG'])
55
+ STDERR.sync = true
56
+ end
57
+
58
+ class MiniTest::Test
59
+ def debug_channel
60
+ ENV['DEBUG'] ? STDERR : nil
61
+ end
62
+
55
63
  def engine
56
64
  exception = nil
65
+ test_thread = nil
57
66
 
58
- ThreadsWait.all_waits(
67
+ engine_thread =
59
68
  Thread.new do
60
69
  Thread.abort_on_exception = true
61
70
 
62
71
  # Create a thread for the engine to run on
63
72
  begin
64
73
  EventMachine.run
74
+
65
75
  rescue Object => exception
66
76
  end
67
- end,
77
+ end
78
+
79
+ test_thread =
68
80
  Thread.new do
69
81
  # Execute the test code in a separate thread to avoid blocking
70
82
  # the EventMachine loop.
71
83
  begin
84
+ while (!EventMachine.reactor_running?)
85
+ # Wait impatiently.
86
+ end
87
+
72
88
  yield
73
89
  rescue Object => exception
74
90
  ensure
75
91
  begin
76
92
  EventMachine.stop_event_loop
77
93
  rescue Object
94
+ STDERR.puts("[#{exception.class}] #{exception}")
78
95
  # Shutting down may trigger an exception from time to time
79
96
  # if the engine itself has failed.
80
97
  end
81
98
  end
82
99
  end
83
- )
100
+
101
+ test_thread.join
102
+
103
+ begin
104
+ Timeout.timeout(1) do
105
+ engine_thread.join
106
+ end
107
+ rescue Timeout::Error
108
+ engine_thread.kill
109
+
110
+ fail 'Execution timed out'
111
+ end
84
112
 
85
113
  if (exception)
86
114
  raise exception
@@ -89,6 +117,7 @@ class Test::Unit::TestCase
89
117
 
90
118
  def assert_timeout(time, message = nil, &block)
91
119
  Timeout::timeout(time, &block)
120
+
92
121
  rescue Timeout::Error
93
122
  flunk(message || 'assert_timeout timed out')
94
123
  end
@@ -106,12 +135,12 @@ class Test::Unit::TestCase
106
135
  end
107
136
 
108
137
  def assert_mapping(map, &block)
109
- result_map = map.inject({ }) do |h, (k,v)|
138
+ result_map = map.inject({ }) do |h, (k, _v)|
110
139
  h[k] = yield(k)
111
140
  h
112
141
  end
113
142
 
114
- differences = result_map.inject([ ]) do |a, (k,v)|
143
+ differences = result_map.inject([ ]) do |a, (k, v)|
115
144
  if (v != map[k])
116
145
  a << k
117
146
  end
@@ -123,14 +152,4 @@ class Test::Unit::TestCase
123
152
  end
124
153
  end
125
154
 
126
- require 'ostruct'
127
-
128
- TestConfig = OpenStruct.new
129
-
130
- config_file = File.expand_path("config.rb", File.dirname(__FILE__))
131
-
132
- if (File.exist?(config_file))
133
- require config_file
134
- else
135
- raise "No test/config.rb file found. Copy and modify test/config.example.rb"
136
- end
155
+ require_relative 'config'
@@ -1,6 +1,6 @@
1
- require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
1
+ require_relative '../helper'
2
2
 
3
- class RemailerIMAPClientInterpreterTest < Test::Unit::TestCase
3
+ class RemailerIMAPClientInterpreterTest < MiniTest::Test
4
4
  def test_split_list_definition
5
5
  assert_mapping(
6
6
  '(\HasChildren \HasNoChildren) "/" "[Gmail]/All Mail"' =>
@@ -1,18 +1,16 @@
1
- require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
1
+ require_relative '../helper'
2
2
 
3
- class RemailerIMAPClientTest < Test::Unit::TestCase
4
- def setup
5
- STDERR.sync = true
6
- end
7
-
3
+ class RemailerIMAPClientTest < MiniTest::Test
8
4
  def test_connect
5
+ skip
6
+
7
+ debug = { }
8
+
9
9
  engine do
10
- debug = { }
11
-
12
10
  client = Remailer::IMAP::Client.open(
13
- TestConfig.imap_server[:host],
14
- :debug => STDERR,
15
- :connect => lambda { |success, host| connected_host = host }
11
+ TestConfig.options[:imap_server][:host],
12
+ debug: self.debug_channel,
13
+ connect: lambda { |_success, host| debug[:connected_host] = host }
16
14
  )
17
15
 
18
16
  assert client
@@ -37,7 +35,7 @@ class RemailerIMAPClientTest < Test::Unit::TestCase
37
35
 
38
36
  login_status = nil
39
37
 
40
- client.login(TestConfig.smtp_server[:username], TestConfig.smtp_server[:password]) do |status, message|
38
+ client.login(TestConfig.options[:smtp_server][:username], TestConfig.options[:smtp_server][:password]) do |status, message|
41
39
  login_status = status
42
40
  end
43
41
 
@@ -1,6 +1,6 @@
1
- require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
1
+ require_relative '../helper'
2
2
 
3
- class RemailerInterpreterStateTest < Test::Unit::TestCase
3
+ class RemailerInterpreterStateTest < MiniTest::Test
4
4
  def test_defaults
5
5
  options = { }
6
6
 
@@ -15,9 +15,9 @@ class RemailerInterpreterStateTest < Test::Unit::TestCase
15
15
  proxy = Remailer::Interpreter::StateProxy.new(options)
16
16
 
17
17
  expected = {
18
- :enter => [ lambda { } ],
19
- :default => [ lambda { } ],
20
- :leave => [ lambda { } ]
18
+ enter: [ lambda { } ],
19
+ default: [ lambda { } ],
20
+ leave: [ lambda { } ]
21
21
  }.freeze
22
22
 
23
23
  proxy.enter(&expected[:enter][0])
@@ -31,9 +31,9 @@ class RemailerInterpreterStateTest < Test::Unit::TestCase
31
31
  options = { }
32
32
 
33
33
  expected = {
34
- :enter => [ lambda { } ],
35
- :terminate => [ lambda { } ],
36
- :leave => [ lambda { } ]
34
+ enter: [ lambda { } ],
35
+ terminate: [ lambda { } ],
36
+ leave: [ lambda { } ]
37
37
  }.freeze
38
38
 
39
39
  Remailer::Interpreter::StateProxy.new(options) do
@@ -49,10 +49,10 @@ class RemailerInterpreterStateTest < Test::Unit::TestCase
49
49
  options = { }
50
50
 
51
51
  expected = {
52
- :enter => [ lambda { } ],
53
- :interpret => [ [ 10, lambda { } ], [ 1, lambda { } ] ],
54
- :default => [ lambda { } ],
55
- :leave => [ lambda { } ]
52
+ enter: [ lambda { } ],
53
+ interpret: [ [ 10, lambda { } ], [ 1, lambda { } ] ],
54
+ default: [ lambda { } ],
55
+ leave: [ lambda { } ]
56
56
  }.freeze
57
57
 
58
58
  Remailer::Interpreter::StateProxy.new(options) do
@@ -80,7 +80,7 @@ class RemailerInterpreterStateTest < Test::Unit::TestCase
80
80
 
81
81
  proxy.leave(&proc[1])
82
82
 
83
- assert_equal({ :enter => [ proc[0] ] }, options_a)
84
- assert_equal({ :leave => [ proc[1] ] }, options_b)
83
+ assert_equal({ enter: [ proc[0] ] }, options_a)
84
+ assert_equal({ leave: [ proc[1] ] }, options_b)
85
85
  end
86
86
  end
@@ -1,4 +1,18 @@
1
- require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
1
+ require_relative '../helper'
2
+
3
+ class RegexpInterpreter < Remailer::Interpreter
4
+ attr_reader :received
5
+
6
+ state :initialized do
7
+ interpret(/^HELO\s+/) do |line|
8
+ @received = [ :helo, line ]
9
+ end
10
+
11
+ interpret(/^MAIL FROM:<([^>]+)>/) do |line|
12
+ @received = [ :mail_from, line ]
13
+ end
14
+ end
15
+ end
2
16
 
3
17
  class ExampleDelegate
4
18
  include TestTriggerHelper
@@ -46,20 +60,6 @@ class LineInterpreterSubclass < LineInterpreter
46
60
  end
47
61
  end
48
62
 
49
- class RegexpInterpreter < Remailer::Interpreter
50
- attr_reader :received
51
-
52
- state :initialized do
53
- interpret(/^HELO\s+/) do |line|
54
- @received = [ :helo, line ]
55
- end
56
-
57
- interpret(/^MAIL FROM:<([^>]+)>/) do |line|
58
- @received = [ :mail_from, line ]
59
- end
60
- end
61
- end
62
-
63
63
  class ExampleInterpreter < Remailer::Interpreter
64
64
  include TestTriggerHelper
65
65
 
@@ -105,15 +105,21 @@ class InterpreterWithAccessor < Remailer::Interpreter
105
105
  attr_accessor :example
106
106
  end
107
107
 
108
- class RemailerInterpreterTest < Test::Unit::TestCase
108
+ class RemailerInterpreterTest < MiniTest::Test
109
109
  def test_default_state
110
- assert_equal [ :initialized, :terminated ], Remailer::Interpreter.states_defined.collect { |s| s.to_s }.sort.collect { |s| s.to_sym }
111
- assert_equal true, Remailer::Interpreter.state_defined?(:initialized)
112
- assert_equal true, Remailer::Interpreter.state_defined?(:terminated)
113
- assert_equal false, Remailer::Interpreter.state_defined?(:unknown)
110
+ test_interpreter_class = Class.new(Remailer::Interpreter)
111
+
112
+ assert test_interpreter_class.states_empty?
113
+
114
+ assert_equal [ :initialized, :terminated ], test_interpreter_class.states_defined.collect { |s| s.to_s }.sort.collect { |s| s.to_sym }
115
+ assert_equal true, test_interpreter_class.state_defined?(:initialized)
116
+ assert_equal true, test_interpreter_class.state_defined?(:terminated)
117
+ assert_equal false, test_interpreter_class.state_defined?(:unknown)
118
+
119
+ assert_equal [ :initialized, :terminated ], test_interpreter_class.states_defined
120
+
121
+ interpreter = test_interpreter_class.new
114
122
 
115
- interpreter = Remailer::Interpreter.new
116
-
117
123
  assert_equal :initialized, interpreter.state
118
124
 
119
125
  buffer = 'a'
@@ -124,13 +130,15 @@ class RemailerInterpreterTest < Test::Unit::TestCase
124
130
  end
125
131
 
126
132
  def test_delegate
133
+ test_interpreter_class = Class.new(Remailer::Interpreter)
134
+
127
135
  delegate = ExampleDelegate.new
128
136
 
129
137
  assert delegate.triggered
130
138
 
131
- interpreter = Remailer::Interpreter.new(:delegate => delegate)
139
+ interpreter = test_interpreter_class.new(delegate: delegate)
132
140
 
133
- assert_equal nil, delegate.attribute
141
+ assert_nil delegate.attribute
134
142
  assert_equal false, delegate.triggered[:method_no_args]
135
143
  assert_equal false, delegate.triggered[:method_with_args]
136
144
 
@@ -228,7 +236,7 @@ class RemailerInterpreterTest < Test::Unit::TestCase
228
236
 
229
237
  interpreter.process(line)
230
238
 
231
- assert_equal nil, interpreter.lines[-1]
239
+ assert_nil interpreter.lines[-1]
232
240
  assert_equal "TEST", line
233
241
 
234
242
  line << "\0"
@@ -242,7 +250,7 @@ class RemailerInterpreterTest < Test::Unit::TestCase
242
250
  def test_regexp_interpreter
243
251
  interpreter = RegexpInterpreter.new
244
252
 
245
- assert_equal nil, interpreter.received
253
+ assert_nil interpreter.received
246
254
 
247
255
  line = "HELO example.com"
248
256
 
@@ -269,7 +277,7 @@ class RemailerInterpreterTest < Test::Unit::TestCase
269
277
  assert_equal true, interpreter.interpret(:random)
270
278
 
271
279
  assert_equal :branch, interpreter.state
272
- assert_equal nil, interpreter.error
280
+ assert_nil interpreter.error
273
281
 
274
282
  assert_equal :random, interpreter.reply
275
283
  end
@@ -291,7 +299,7 @@ class RemailerInterpreterTest < Test::Unit::TestCase
291
299
  def test_new_with_block
292
300
  interpreter = InterpreterWithAccessor.new
293
301
 
294
- assert_equal nil, interpreter.example
302
+ assert_nil interpreter.example
295
303
 
296
304
  interpreter = InterpreterWithAccessor.new do |interpreter|
297
305
  interpreter.example = 'example'