pigeon 0.9.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fa0f5ce613ef0b66cded863d01259e09099eeb27
4
+ data.tar.gz: 6b1d997dda5b4664c6cf77524a840aee230ac54d
5
+ SHA512:
6
+ metadata.gz: 18a1edfd20eaec356b8297665db24eb96d18e2e90fb8c7699a71e081c599f3d809476e64d7e05dae8fedd3a7973a924c6500013c90bacb0483dcfdddd7ee2de4
7
+ data.tar.gz: 3c9bc25b916a9b5ca262ed489c117032185b5fc3e8ffc9feab37f94dd8b7d7f4df5a394063d48dfe0945834ef7a9fedd0d604d50f75162f8fa6e25833dc3771d
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem install bundler
4
+ rvm:
5
+ - 1.9.3-p551
6
+ - 2.0.0-p598
7
+ - 2.1.5
8
+ - 2.2.0
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gem 'eventmachine'
4
+
5
+ group :development do
6
+ gem 'minitest-reporters', path: '~/git/minitest-reporters'
7
+ gem 'minitest'
8
+ gem 'jeweler'
9
+ end
data/README.md CHANGED
@@ -79,4 +79,4 @@ This engine is currently in development.
79
79
 
80
80
  ## Copyright
81
81
 
82
- Copyright (c) 2009-2013 Scott Tadman, The Working Group
82
+ Copyright (c) 2009-2015 Scott Tadman, The Working Group
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require 'rake'
3
3
 
4
4
  begin
5
5
  require 'jeweler'
6
+
6
7
  Jeweler::Tasks.new do |gem|
7
8
  gem.name = "pigeon"
8
9
  gem.summary = %Q{Simple daemonized EventMachine engine framework with plug-in support}
@@ -10,21 +11,20 @@ begin
10
11
  gem.email = "github@tadman.ca"
11
12
  gem.homepage = "http://github.com/twg/pigeon"
12
13
  gem.authors = %w[ tadman ]
13
- gem.add_development_dependency 'eventmachine'
14
14
  gem.executables = [ ]
15
15
  end
16
+
16
17
  Jeweler::GemcutterTasks.new
17
18
  rescue LoadError
18
19
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
20
  end
20
21
 
21
22
  require 'rake/testtask'
23
+
22
24
  Rake::TestTask.new(:test) do |test|
23
25
  test.libs << 'lib' << 'test'
24
26
  test.pattern = 'test/**/*_test.rb'
25
27
  test.verbose = true
26
28
  end
27
29
 
28
- task :test => :check_dependencies
29
-
30
- task :default => :test
30
+ task default: :test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.3
1
+ 1.0.0
@@ -13,6 +13,14 @@ module Pigeon
13
13
  autoload(:SortedArray, 'pigeon/sorted_array')
14
14
  autoload(:Support, 'pigeon/support')
15
15
  autoload(:Task, 'pigeon/task')
16
+
17
+ # == Module Methods =======================================================
18
+
19
+ def self.version
20
+ @version ||= File.readlines(
21
+ File.expand_path('../VERSION'), File.dirname(__FILE__)
22
+ )[0].chomp
23
+ end
16
24
  end
17
25
 
18
26
  # NOTE: This file needs to be directly loaded due to some kind of peculiar
@@ -10,7 +10,7 @@ class Pigeon::Dispatcher
10
10
  # == Properties ===========================================================
11
11
 
12
12
  option_accessor :thread_limit,
13
- :default => 24
13
+ default: 24
14
14
 
15
15
  attr_reader :exceptions
16
16
 
@@ -21,29 +21,29 @@ class Pigeon::Engine
21
21
  option_accessor :name
22
22
  option_accessor :pid_file_name
23
23
  option_accessor :foreground,
24
- :boolean => true
24
+ boolean: true
25
25
  option_accessor :debug,
26
- :boolean => true
26
+ boolean: true
27
27
  option_accessor :log_rotation
28
28
  option_accessor :engine_log_name,
29
- :default => 'engine.log'
29
+ default: 'engine.log'
30
30
  option_accessor :engine_logger
31
31
  option_accessor :query_log_name,
32
- :default => 'query.log'
32
+ default: 'query.log'
33
33
  option_accessor :query_logger
34
34
  option_accessor :try_pid_dirs,
35
- :default => %w[
35
+ default: %w[
36
36
  /var/run
37
37
  /tmp
38
38
  ].freeze
39
39
  option_accessor :try_log_dirs,
40
- :default => %w[
40
+ default: %w[
41
41
  /var/log
42
42
  /tmp
43
43
  ].freeze
44
44
  option_accessor :threaded,
45
- :boolean => true,
46
- :default => false
45
+ boolean: true,
46
+ default: false
47
47
 
48
48
  attr_reader :id
49
49
  attr_reader :state
@@ -125,14 +125,14 @@ class Pigeon::Engine
125
125
  EventMachine.run do
126
126
  engine = new(options)
127
127
 
128
- yield(engine) if (block_given?)
129
-
130
128
  Signal.trap('INT') do
131
129
  engine.terminate
132
130
  end
133
131
 
134
132
  Pigeon::Engine.register_engine(engine)
135
133
 
134
+ yield(engine) if (block_given?)
135
+
136
136
  engine.run
137
137
  end
138
138
 
@@ -148,7 +148,7 @@ class Pigeon::Engine
148
148
 
149
149
  pid = Pigeon::Support.daemonize(logger) do
150
150
  launch({
151
- :logger => logger
151
+ logger: logger
152
152
  }.merge(options || { }))
153
153
  end
154
154
 
@@ -162,7 +162,7 @@ class Pigeon::Engine
162
162
  def self.run
163
163
  yield($$) if (block_given?)
164
164
 
165
- launch(:foreground => true)
165
+ launch(foreground: true)
166
166
  end
167
167
 
168
168
  def self.stop
@@ -171,6 +171,7 @@ class Pigeon::Engine
171
171
  if (pid)
172
172
  begin
173
173
  Process.kill('INT', pid)
174
+
174
175
  rescue Errno::ESRCH
175
176
  # No such process exception
176
177
  pid = nil
@@ -178,7 +179,7 @@ class Pigeon::Engine
178
179
 
179
180
  begin
180
181
  while (Process.kill(0, pid))
181
- sleep(1)
182
+ Pigeon::Support.nap(0.1)
182
183
  end
183
184
  rescue Errno::ESRCH
184
185
  # No such process, already terminated
@@ -195,8 +196,11 @@ class Pigeon::Engine
195
196
  end
196
197
 
197
198
  def self.restart
198
- self.stop
199
- self.start
199
+ self.stop do |old_pid|
200
+ self.start do |pid|
201
+ yield(pid, old_pid) if (block_given?)
202
+ end
203
+ end
200
204
  end
201
205
 
202
206
  def self.running?
@@ -248,6 +252,10 @@ class Pigeon::Engine
248
252
  def self.unregister_engine(engine)
249
253
  @engines.delete(engine)
250
254
  end
255
+
256
+ def self.clear_engines!
257
+ @engines = [ ]
258
+ end
251
259
 
252
260
  # Schedules a block for execution on the main EventMachine thread. This is
253
261
  # a wrapper around the EventMachine.schedule method.
@@ -359,7 +367,10 @@ class Pigeon::Engine
359
367
  # events.
360
368
  def terminate
361
369
  wrap_chain(:stop) do
362
- EventMachine.stop_event_loop
370
+ if (EventMachine.reactor_running?)
371
+ EventMachine.stop_event_loop
372
+ end
373
+
363
374
  @state = :terminated
364
375
  end
365
376
  end
@@ -18,24 +18,53 @@ class Pigeon::Launcher
18
18
  end
19
19
 
20
20
  def handle_args(*args)
21
- op = OptionParser.new
21
+ op = OptionParser.new do |parser|
22
+ parser.on('-v', '--version') do
23
+ pigeon_version = 'Pigeon %s' % Pigeon.version
24
+
25
+ version =
26
+ if (@engine.respond_to?(:version))
27
+ '%s (%s)' % [ @engine.version, pigeon_version ]
28
+ else
29
+ pigeon_version
30
+ end
31
+
32
+ puts version
33
+ exit(0)
34
+ end
35
+ end
22
36
 
23
37
  command = op.parse(*args.flatten).first
24
38
 
25
39
  begin
26
40
  case (command)
27
41
  when 'start'
28
- @engine.start(&method(:start))
42
+ @engine.start do |pid|
43
+ yield(pid) if (block_given?)
44
+ self.start(pid)
45
+ end
29
46
  when 'stop'
30
- @engine.stop(&method(:stop))
47
+ @engine.stop do |pid|
48
+ yield(pid) if (block_given?)
49
+ self.stop(pid)
50
+ end
31
51
  when 'restart'
32
- @engine.restart(&method(:restart))
52
+ @engine.restart do |pid, old_pid|
53
+ yield(pid, old_pid) if (block_given?)
54
+ self.restart(pid, old_pid)
55
+ end
33
56
  when 'status'
34
- @engine.status(&method(:status))
57
+ @engine.status do |pid|
58
+ yield(pid) if (block_given?)
59
+ self.status(pid)
60
+ end
35
61
  when 'run'
36
62
  @engine.engine_logger = Pigeon::Logger.new(STDOUT)
37
63
 
38
- @engine.run(&method(:run))
64
+ @engine.run do |pid|
65
+ yield(pid) if (block_given?)
66
+ self.run(pid)
67
+ end
39
68
  else
40
69
  usage
41
70
  end
@@ -30,7 +30,6 @@ module Pigeon::Support
30
30
  if (thread.backtrace)
31
31
  logger.error("\t" + thread.backtrace.join("\n\t"))
32
32
  end
33
-
34
33
  end
35
34
  end
36
35
 
@@ -39,22 +38,41 @@ module Pigeon::Support
39
38
  end
40
39
 
41
40
  begin
42
- Process.wait(daemon_pid)
41
+ interrupted = false
42
+
43
+ Signal.trap('INT') do
44
+ interrupted = true
45
+ Process.kill('INT', daemon_pid)
46
+
47
+ relaunch = false
48
+ end
49
+
50
+ pid, status = Process.wait2(daemon_pid)
51
+
52
+ if (interrupted)
53
+ logger.info("Supervisor #{Process.pid} received termination signal, shut down child #{daemon_pid}")
54
+ end
43
55
 
44
56
  # A non-zero exit status indicates some sort of error, so the
45
57
  # process will be relaunched after a short delay.
46
58
  relaunch = ($? != 0)
47
59
 
48
- rescue Interrupt
49
- Process.kill('INT', daemon_pid)
50
-
51
- relaunch = false
60
+ ensure
61
+ # Reset Signal handler before forking again
62
+ Signal.trap('INT') do
63
+ end
52
64
  end
53
65
 
54
66
  if (relaunch)
55
- logger.info("Will relaunch in %d seconds" % delay)
67
+ begin
68
+ logger.info("Supervisor #{Process.pid} will relaunch in %d seconds" % delay)
69
+ sleep(delay)
70
+
71
+ rescue Interrupt
72
+ logger.info("Supervisor #{Process.pid} abandoing restart because of termination")
56
73
 
57
- sleep(delay)
74
+ relaunch = false
75
+ end
58
76
  else
59
77
  logger.info("Terminated normally")
60
78
  end
@@ -66,13 +84,17 @@ module Pigeon::Support
66
84
  wfd.close
67
85
  end
68
86
 
69
- Process.wait(forked_pid)
87
+ pid, status = Process.wait2(forked_pid)
70
88
 
71
89
  daemon_pid = rfd.readline
72
90
  rfd.close
73
91
 
74
92
  daemon_pid.to_i
75
93
  end
94
+
95
+ def nap(time)
96
+ select(nil, nil, nil, time.to_f)
97
+ end
76
98
 
77
99
  # Finds the first directory in the given list that exists and is
78
100
  # writable. Returns nil if none match.
@@ -1,4 +1,9 @@
1
1
  class Pigeon::Task
2
+ # == Exceptions ===========================================================
3
+
4
+ class EngineRequired < StandardError
5
+ end
6
+
2
7
  # == Constants ============================================================
3
8
 
4
9
  # == Properties ===========================================================
@@ -35,6 +40,10 @@ class Pigeon::Task
35
40
  @context = context
36
41
  @engine = engine || Pigeon::Engine.default_engine
37
42
  @created_at = Time.now
43
+
44
+ unless (@engine)
45
+ raise EngineRequired, "Task creation requires an active Pigeon::Engine"
46
+ end
38
47
 
39
48
  after_initialized
40
49
  end
@@ -2,14 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: pigeon 1.0.0 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "pigeon"
8
- s.version = "0.9.3"
9
+ s.version = "1.0.0"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
11
13
  s.authors = ["tadman"]
12
- s.date = "2013-04-26"
14
+ s.date = "2015-02-18"
13
15
  s.description = "Pigeon is a simple way to get started building an EventMachine engine that's intended to run as a background job."
14
16
  s.email = "github@tadman.ca"
15
17
  s.extra_rdoc_files = [
@@ -18,6 +20,8 @@ Gem::Specification.new do |s|
18
20
  ]
19
21
  s.files = [
20
22
  ".document",
23
+ ".travis.yml",
24
+ "Gemfile",
21
25
  "LICENSE",
22
26
  "README.md",
23
27
  "Rakefile",
@@ -51,20 +55,28 @@ Gem::Specification.new do |s|
51
55
  "test/unit/pigeon_test.rb"
52
56
  ]
53
57
  s.homepage = "http://github.com/twg/pigeon"
54
- s.require_paths = ["lib"]
55
- s.rubygems_version = "1.8.25"
58
+ s.rubygems_version = "2.2.2"
56
59
  s.summary = "Simple daemonized EventMachine engine framework with plug-in support"
57
60
 
58
61
  if s.respond_to? :specification_version then
59
- s.specification_version = 3
62
+ s.specification_version = 4
60
63
 
61
64
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
62
- s.add_development_dependency(%q<eventmachine>, [">= 0"])
65
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
66
+ s.add_development_dependency(%q<minitest-reporters>, [">= 0"])
67
+ s.add_development_dependency(%q<minitest>, [">= 0"])
68
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
63
69
  else
64
70
  s.add_dependency(%q<eventmachine>, [">= 0"])
71
+ s.add_dependency(%q<minitest-reporters>, [">= 0"])
72
+ s.add_dependency(%q<minitest>, [">= 0"])
73
+ s.add_dependency(%q<jeweler>, [">= 0"])
65
74
  end
66
75
  else
67
76
  s.add_dependency(%q<eventmachine>, [">= 0"])
77
+ s.add_dependency(%q<minitest-reporters>, [">= 0"])
78
+ s.add_dependency(%q<minitest>, [">= 0"])
79
+ s.add_dependency(%q<jeweler>, [">= 0"])
68
80
  end
69
81
  end
70
82
 
@@ -1,35 +1,63 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
2
+ require 'bundler/setup'
3
3
 
4
- $LOAD_PATH.unshift(File.expand_path(*%w[ .. lib ]), File.dirname(__FILE__))
5
- $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ require 'minitest'
6
5
 
7
- require 'timeout'
6
+ module Minitest
7
+ # The default Minitest behavior to intercept at_exit and rewrite the exit
8
+ # status code based on test results is okay for the parent process, but
9
+ # causes friction when using fork within tests. Here it's disabled unless
10
+ # the process terminating is the parent.
11
+ def self.autorun
12
+ return if (@at_exit_hook_installed)
8
13
 
9
- require 'rubygems'
14
+ @at_exit_hook_installed = Process.pid
15
+
16
+ at_exit do
17
+ next if $! and not ($!.kind_of? SystemExit and $!.success?)
18
+
19
+ exit_code = Minitest.run(ARGV)
20
+
21
+ @@after_run.reverse_each do |block|
22
+ block.call
23
+
24
+ if (Process.pid != @at_exit_hook_installed)
25
+ break
26
+ end
27
+ end
10
28
 
11
- begin
12
- gem 'eventmachine'
13
- rescue => e
14
- raise "EventMachine gem is not installed or could not be loaded: [#{e.class}] #{e}"
29
+ exit(exit_code)
30
+ end
31
+ end
15
32
  end
16
33
 
34
+ require 'minitest/reporters'
35
+ require 'minitest/autorun'
36
+ require 'timeout'
37
+
38
+ Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new)
39
+
40
+ $LOAD_PATH.unshift(File.expand_path(File.join(*%w[ .. lib ]), File.dirname(__FILE__)))
41
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
42
+
17
43
  require 'pigeon'
44
+ require 'eventmachine'
18
45
 
19
- class Test::Unit::TestCase
46
+ class Minitest::Test
20
47
  def assert_timeout(time, message = nil, &block)
21
48
  Timeout::timeout(time, &block)
49
+
22
50
  rescue Timeout::Error
23
51
  flunk(message || 'assert_timeout timed out')
24
52
  end
25
53
 
26
54
  def assert_eventually(time = nil, message = nil, &block)
27
- start_time = Time.now.to_i
55
+ start_time = Time.now.to_f
28
56
 
29
57
  while (!block.call)
30
58
  select(nil, nil, nil, 0.1)
31
59
 
32
- if (time and (Time.now.to_i - start_time > time))
60
+ if (time and (Time.now.to_f - start_time > time))
33
61
  flunk(message || 'assert_eventually timed out')
34
62
  end
35
63
  end
@@ -37,32 +65,64 @@ class Test::Unit::TestCase
37
65
 
38
66
  def engine
39
67
  exception = nil
68
+ test_thread = nil
40
69
 
41
- Pigeon::Engine.launch do |new_engine|
42
- @engine = new_engine
70
+ engine_thread =
71
+ Thread.new do
72
+ Thread.abort_on_exception = true
73
+
74
+ Pigeon::Engine.clear_engines!
75
+
76
+ # Create a thread for the engine to run on
77
+ begin
78
+ Pigeon::Engine.launch do |launched|
79
+ @engine = launched
80
+ end
81
+
82
+ rescue Object => exception
83
+ end
84
+ end
43
85
 
44
- # Execute the test code in a separate thread to avoid blocking
45
- # the EventMachine loop.
86
+ test_thread =
46
87
  Thread.new do
88
+ # Execute the test code in a separate thread to avoid blocking
89
+ # the EventMachine loop.
47
90
  begin
48
- Thread.abort_on_exception = true
49
- yield
91
+ while (!@engine or Pigeon::Engine.default_engine != @engine)
92
+ # Wait impatiently.
93
+ end
94
+
95
+ yield(@engine)
50
96
  rescue Object => exception
51
97
  ensure
52
98
  begin
53
- # Regardless what happened, always terminate the engine.
54
- @engine.terminate
55
- rescue Object => e
99
+ if (EventMachine.reactor_running?)
100
+ EventMachine.stop_event_loop
101
+ end
102
+ rescue Object
103
+ STDERR.puts("[#{exception.class}] #{exception}")
56
104
  # Shutting down may trigger an exception from time to time
57
105
  # if the engine itself has failed.
58
- STDERR.puts("Exception: [#{e.class}] #{e}")
59
106
  end
60
107
  end
61
108
  end
109
+
110
+ test_thread.join
111
+
112
+ begin
113
+ Timeout.timeout(1) do
114
+ engine_thread.join
115
+ end
116
+ rescue Timeout::Error
117
+ engine_thread.kill
62
118
  end
63
119
 
64
120
  if (exception)
65
121
  raise exception
66
122
  end
123
+ ensure
124
+ if (engine_thread)
125
+ engine_thread.kill
126
+ end
67
127
  end
68
128
  end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class PigeonQueueTest < Test::Unit::TestCase
3
+ class PigeonQueueTest < Minitest::Test
4
4
  def test_empty_queue
5
5
  queue = Pigeon::Queue.new
6
6
 
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class PigeonDispatcherTest < Test::Unit::TestCase
3
+ class PigeonDispatcherTest < Minitest::Test
4
4
  def test_routine_dispatching
5
5
  dispatcher = Pigeon::Dispatcher.new
6
6
 
@@ -71,10 +71,12 @@ class ShutdownCallbackTestEngine < Pigeon::Engine
71
71
  end
72
72
  end
73
73
 
74
- class TestPigeonEngine < Test::Unit::TestCase
74
+ class TestPigeonEngine < Minitest::Test
75
75
  def test_default_options
76
76
  assert TestEngine.engine_logger
77
77
  assert TestEngine.engine_logger.is_a?(Logger)
78
+
79
+ assert_equal nil, TestEngine.default_engine
78
80
  end
79
81
 
80
82
  def test_example_subclass
@@ -82,13 +84,13 @@ class TestPigeonEngine < Test::Unit::TestCase
82
84
 
83
85
  read_fd, write_fd = IO.pipe
84
86
 
85
- TestEngine.start(:pipe => write_fd) do |pid|
87
+ TestEngine.start(pipe: write_fd) do |pid|
86
88
  assert pid
87
89
  engine_pid = pid
88
90
  end
89
91
 
90
92
  write_fd.close
91
-
93
+
92
94
  Timeout::timeout(5) do
93
95
  assert_equal "STARTED\n", read_fd.readline
94
96
  end
@@ -96,7 +98,7 @@ class TestPigeonEngine < Test::Unit::TestCase
96
98
  TestEngine.status do |pid|
97
99
  assert_equal engine_pid, pid
98
100
  end
99
-
101
+
100
102
  TestEngine.stop do |pid|
101
103
  assert_equal engine_pid, pid
102
104
  end
@@ -111,7 +113,7 @@ class TestPigeonEngine < Test::Unit::TestCase
111
113
 
112
114
  read_fd, write_fd = IO.pipe
113
115
 
114
- engine_pid = TestEngine.start(:pipe => write_fd)
116
+ engine_pid = TestEngine.start(pipe: write_fd)
115
117
 
116
118
  write_fd.close
117
119
 
@@ -135,7 +137,7 @@ class TestPigeonEngine < Test::Unit::TestCase
135
137
 
136
138
  read_fd, write_fd = IO.pipe
137
139
 
138
- CallbackTestEngine.start(:pipe => write_fd) do |pid|
140
+ CallbackTestEngine.start(pipe: write_fd) do |pid|
139
141
  assert pid
140
142
  engine_pid = pid
141
143
  end
@@ -169,6 +171,23 @@ class TestPigeonEngine < Test::Unit::TestCase
169
171
 
170
172
  assert_equal expected_callbacks, read_fd.read.split(/\n/).collect(&:to_sym)
171
173
  end
174
+
175
+ def test_fork_exitstatus
176
+ child_pid = fork do
177
+ end
178
+
179
+ pid, status = Process.wait2(child_pid)
180
+
181
+ assert_equal 0, status.exitstatus
182
+
183
+ child_pid = fork do
184
+ exit(90)
185
+ end
186
+
187
+ pid, status = Process.wait2(child_pid)
188
+
189
+ assert_equal 90, status.exitstatus
190
+ end
172
191
 
173
192
  def test_shutdown_engine
174
193
  engine_pid = nil
@@ -179,15 +198,12 @@ class TestPigeonEngine < Test::Unit::TestCase
179
198
 
180
199
  assert engine_pid
181
200
 
182
- sleep(1)
183
-
184
- running_pid = nil
185
-
186
- ShutdownEngine.status do |pid|
187
- running_pid = pid
201
+ assert_eventually(5) do
202
+ !ShutdownEngine.status
188
203
  end
189
-
190
- assert_equal nil, running_pid
204
+
205
+ ensure
206
+ ShutdownEngine.stop
191
207
  end
192
208
 
193
209
  def test_shutdown_engine_with_blocking_callback
@@ -6,7 +6,7 @@ class Pigeon::Launcher
6
6
  end
7
7
  end
8
8
 
9
- class PigeonLauncherTest < Test::Unit::TestCase
9
+ class PigeonLauncherTest < Minitest::Test
10
10
  def test_default_launcher
11
11
  pid = Pigeon::Launcher.launch
12
12
 
@@ -19,41 +19,40 @@ class PigeonLauncherTest < Test::Unit::TestCase
19
19
  end
20
20
 
21
21
  def test_triggers
22
- triggered = Hash.new do |h, k|
23
- h[k] = 0
24
- end
22
+ launcher = Pigeon::Launcher.new(Pigeon::Engine)
23
+
24
+ triggered = Hash.new { |h,k| h[k] = [ ] }
25
25
 
26
- Pigeon::Launcher.new(Pigeon::Engine).handle_args('start') do
27
- start do
28
- triggered[:start] += 1
29
- end
26
+ launcher.handle_args('start') do |pid|
27
+ triggered[:start] << pid
30
28
  end
31
29
 
32
- Pigeon::Launcher.new(Pigeon::Engine).handle_args('restart') do
33
- restart do
34
- triggered[:restart] += 1
35
- end
30
+ launcher.handle_args('status') do |pid|
31
+ triggered[:status] << pid
36
32
  end
37
33
 
38
- Pigeon::Launcher.new(Pigeon::Engine).handle_args('status') do
39
- status do
40
- triggered[:status] += 1
41
- end
34
+ launcher.handle_args('restart') do |pid, old_pid|
35
+ triggered[:restart] << pid
42
36
  end
43
37
 
44
- Pigeon::Launcher.new(Pigeon::Engine).handle_args('stop') do
45
- stop do
46
- triggered[:stop] += 1
47
- end
38
+ launcher.handle_args('status') do |pid|
39
+ triggered[:status] << pid
48
40
  end
49
-
50
- # FIX: Test `run`
51
-
52
- if (false)
53
- assert_equal 1, triggered[:start]
54
- assert_equal 1, triggered[:restart]
55
- assert_equal 1, triggered[:status]
56
- assert_equal 1, triggered[:stop]
41
+
42
+ launcher.handle_args('stop') do |pid|
43
+ triggered[:stop] << pid
57
44
  end
45
+
46
+ assert triggered[:start]
47
+ assert_equal 1, triggered[:start].length
48
+
49
+
50
+ assert triggered[:restart]
51
+ assert_equal 1, triggered[:restart].length
52
+ refute_equal triggered[:start], triggered[:restart]
53
+
54
+ assert_equal triggered[:start] + triggered[:restart], triggered[:status]
55
+
56
+ assert_equal triggered[:restart], triggered[:stop]
58
57
  end
59
58
  end
@@ -6,10 +6,10 @@ class OptionClass
6
6
  option_accessor :single_option
7
7
  option_accessor :multi1, :multi2
8
8
  option_accessor :option_with_default,
9
- :default => :example_default
9
+ default: :example_default
10
10
 
11
11
  option_accessor :boolean_option,
12
- :boolean => true
12
+ boolean: true
13
13
 
14
14
  self.single_option = :single_option_default
15
15
  end
@@ -17,7 +17,7 @@ end
17
17
  class OptionSubclass < OptionClass
18
18
  end
19
19
 
20
- class PigeonOptionAccessorTest < Test::Unit::TestCase
20
+ class PigeonOptionAccessorTest < Minitest::Test
21
21
  def test_class_and_instance_chaining
22
22
  assert_equal :single_option_default, OptionClass.single_option
23
23
 
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class PigeonProcessorTest < Test::Unit::TestCase
3
+ class PigeonProcessorTest < Minitest::Test
4
4
  class TaggedTask < Pigeon::Task
5
5
  attr_accessor :tag
6
6
  attr_reader :last_task
@@ -9,6 +9,10 @@ class PigeonProcessorTest < Test::Unit::TestCase
9
9
  super(options)
10
10
  @tag = tag
11
11
  end
12
+
13
+ def state_initialized!
14
+ transition_to_state(:finished)
15
+ end
12
16
 
13
17
  def inspect
14
18
  "<#{@tag}>"
@@ -46,7 +50,7 @@ class PigeonProcessorTest < Test::Unit::TestCase
46
50
  end
47
51
 
48
52
  assert_equal false, processor.task?
49
-
53
+
50
54
  queue << TaggedTask.new(0)
51
55
 
52
56
  assert_eventually(1) do
@@ -71,16 +75,18 @@ class PigeonProcessorTest < Test::Unit::TestCase
71
75
  end
72
76
 
73
77
  def test_on_backlog
74
- queue = Pigeon::Queue.new
75
-
76
- 100.times do |n|
77
- queue << TaggedTask.new(n)
78
- end
79
-
80
- processor = Pigeon::Processor.new(queue)
81
-
82
- assert_eventually(5) do
83
- queue.empty?
78
+ engine do
79
+ queue = Pigeon::Queue.new
80
+
81
+ 100.times do |n|
82
+ queue << TaggedTask.new(n)
83
+ end
84
+
85
+ processor = Pigeon::Processor.new(queue)
86
+
87
+ assert_eventually(5) do
88
+ queue.empty?
89
+ end
84
90
  end
85
91
  end
86
92
 
@@ -145,7 +151,7 @@ class PigeonProcessorTest < Test::Unit::TestCase
145
151
  queue << TaggedTask.new(n)
146
152
  end
147
153
 
148
- assert_eventually(2) do
154
+ assert_eventually(5) do
149
155
  queue.length == count
150
156
  end
151
157
 
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class PigeonQueueTest < Test::Unit::TestCase
3
+ class PigeonQueueTest < Minitest::Test
4
4
  class TaggedTask < Pigeon::Task
5
5
  attr_accessor :tag
6
6
 
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class PigeonSchedulerTest < Test::Unit::TestCase
3
+ class PigeonSchedulerTest < Minitest::Test
4
4
  class TaggedTask < Pigeon::Task
5
5
  attr_accessor :tag
6
6
 
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class PigeonSortedArrayTest < Test::Unit::TestCase
3
+ class PigeonSortedArrayTest < Minitest::Test
4
4
  def test_empty_state
5
5
  array = Pigeon::SortedArray.new
6
6
 
@@ -21,13 +21,13 @@ class PigeonSortedArrayTest < Test::Unit::TestCase
21
21
  def test_does_sorting
22
22
  array = Pigeon::SortedArray.new
23
23
 
24
- test_array = [2, 2, 2, 2, 3, 3, 3]
24
+ test_array = [ 2, 2, 2, 2, 3, 3, 3 ]
25
25
 
26
26
  test_array.each do |i|
27
27
  array << i
28
28
  end
29
29
 
30
- assert_equal [2, 2, 2, 2, 3, 3, 3], array.to_a
30
+ assert_equal [ 2, 2, 2, 2, 3, 3, 3 ], array.to_a
31
31
  end
32
32
 
33
33
  def test_does_sorting_with_insertion_in_order
@@ -1,5 +1,11 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
+ class TerminateTask < Pigeon::Task
4
+ def state_initialized!
5
+ transition_to_state(:finished)
6
+ end
7
+ end
8
+
3
9
  class ExampleTask < Pigeon::Task
4
10
  attr_accessor :triggers
5
11
 
@@ -43,10 +49,10 @@ class FailingTask < Pigeon::Task
43
49
  end
44
50
  end
45
51
 
46
- class PigeonTaskTest < Test::Unit::TestCase
52
+ class PigeonTaskTest < Minitest::Test
47
53
  def test_empty_task
48
54
  engine do
49
- task = Pigeon::Task.new
55
+ task = TerminateTask.new
50
56
 
51
57
  reported = 0
52
58
 
@@ -68,14 +74,19 @@ class PigeonTaskTest < Test::Unit::TestCase
68
74
  end
69
75
 
70
76
  def test_alternate_engine
71
- engine = Pigeon::Engine.new
72
- task = Pigeon::Task.new(nil, engine)
73
-
74
- assert_equal engine.object_id, task.engine.object_id
77
+ engine do |default_engine|
78
+ engine = Pigeon::Engine.new
79
+
80
+ refute_equal default_engine.object_id, engine.object_id
81
+
82
+ task = Pigeon::Task.new(nil, engine)
83
+
84
+ assert_equal engine.object_id, task.engine.object_id
85
+ end
75
86
  end
76
87
 
77
88
  def test_example_task
78
- engine do
89
+ engine do |launched|
79
90
  task = ExampleTask.new
80
91
 
81
92
  callbacks = [ ]
@@ -137,23 +148,25 @@ class PigeonTaskTest < Test::Unit::TestCase
137
148
  end
138
149
 
139
150
  def test_with_context
140
- options = {
141
- :example => 'example1',
142
- :optional => 1
143
- }.freeze
144
-
145
- task = Pigeon::Task.new(options)
146
-
147
- assert_equal options, task.context
148
-
149
- task.context = 'test'
150
-
151
- assert_equal 'test', task.context
151
+ engine do
152
+ options = {
153
+ example: 'example1',
154
+ optional: 1
155
+ }.freeze
156
+
157
+ task = Pigeon::Task.new(options)
158
+
159
+ assert_equal options, task.context
160
+
161
+ task.context = 'test'
162
+
163
+ assert_equal 'test', task.context
164
+ end
152
165
  end
153
166
 
154
167
  def test_block_notification
155
168
  engine do
156
- task = Pigeon::Task.new
169
+ task = TerminateTask.new
157
170
 
158
171
  states_triggered = [ ]
159
172
 
@@ -170,15 +183,17 @@ class PigeonTaskTest < Test::Unit::TestCase
170
183
  end
171
184
 
172
185
  def test_priority_order
173
- tasks = (0..10).collect do
174
- task = Pigeon::Task.new
186
+ engine do
187
+ tasks = (0..10).collect do
188
+ task = Pigeon::Task.new
175
189
 
176
- # Trigger generation of default priority value
177
- task.priority
190
+ # Trigger generation of default priority value
191
+ task.priority
178
192
 
179
- task
193
+ task
194
+ end
195
+
196
+ assert_equal tasks.collect(&:object_id), tasks.sort.collect(&:object_id)
180
197
  end
181
-
182
- assert_equal tasks.collect(&:object_id), tasks.sort.collect(&:object_id)
183
198
  end
184
199
  end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
- class TestPigeon < Test::Unit::TestCase
3
+ class TestPigeon < Minitest::Test
4
4
  def test_load_module
5
5
  assert Pigeon
6
6
  end
metadata CHANGED
@@ -1,30 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pigeon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - tadman
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-26 00:00:00.000000000 Z
11
+ date: 2015-02-18 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: eventmachine
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest-reporters
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jeweler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
20
60
  - !ruby/object:Gem::Version
21
61
  version: '0'
22
62
  type: :development
23
63
  prerelease: false
24
64
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
65
  requirements:
27
- - - ! '>='
66
+ - - ">="
28
67
  - !ruby/object:Gem::Version
29
68
  version: '0'
30
69
  description: Pigeon is a simple way to get started building an EventMachine engine
@@ -36,7 +75,9 @@ extra_rdoc_files:
36
75
  - LICENSE
37
76
  - README.md
38
77
  files:
39
- - .document
78
+ - ".document"
79
+ - ".travis.yml"
80
+ - Gemfile
40
81
  - LICENSE
41
82
  - README.md
42
83
  - Rakefile
@@ -70,26 +111,25 @@ files:
70
111
  - test/unit/pigeon_test.rb
71
112
  homepage: http://github.com/twg/pigeon
72
113
  licenses: []
114
+ metadata: {}
73
115
  post_install_message:
74
116
  rdoc_options: []
75
117
  require_paths:
76
118
  - lib
77
119
  required_ruby_version: !ruby/object:Gem::Requirement
78
- none: false
79
120
  requirements:
80
- - - ! '>='
121
+ - - ">="
81
122
  - !ruby/object:Gem::Version
82
123
  version: '0'
83
124
  required_rubygems_version: !ruby/object:Gem::Requirement
84
- none: false
85
125
  requirements:
86
- - - ! '>='
126
+ - - ">="
87
127
  - !ruby/object:Gem::Version
88
128
  version: '0'
89
129
  requirements: []
90
130
  rubyforge_project:
91
- rubygems_version: 1.8.25
131
+ rubygems_version: 2.2.2
92
132
  signing_key:
93
- specification_version: 3
133
+ specification_version: 4
94
134
  summary: Simple daemonized EventMachine engine framework with plug-in support
95
135
  test_files: []