remailer 0.5.2 → 0.9.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.
@@ -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'