pigeon 0.9.3 → 1.0.0

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,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: []