rocketjob 0.7.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.
data/test/job_test.rb ADDED
@@ -0,0 +1,186 @@
1
+ require_relative 'test_helper'
2
+ require_relative 'jobs/test_job'
3
+
4
+ # Unit Test for RocketJob::Job
5
+ class JobTest < Minitest::Test
6
+ context RocketJob::Job do
7
+ setup do
8
+ @server = RocketJob::Server.new
9
+ @server.started
10
+ @description = 'Hello World'
11
+ @arguments = [ 1 ]
12
+ @job = Jobs::TestJob.new(
13
+ description: @description,
14
+ arguments: @arguments,
15
+ destroy_on_complete: false
16
+ )
17
+ end
18
+
19
+ teardown do
20
+ @job.destroy if @job && !@job.new_record?
21
+ end
22
+
23
+ context '.config' do
24
+ should 'support multiple databases' do
25
+ assert_equal 'test_rocket_job', RocketJob::Job.collection.db.name
26
+ end
27
+ end
28
+
29
+ context '#reload' do
30
+ should 'handle hash' do
31
+ @job = Jobs::TestJob.new(
32
+ description: @description,
33
+ arguments: [ { key: 'value' } ],
34
+ destroy_on_complete: false
35
+ )
36
+
37
+ assert_equal 'value', @job.arguments.first[:key]
38
+ @job.save!
39
+ @job.reload
40
+ assert @job.arguments.first.is_a?(ActiveSupport::HashWithIndifferentAccess), @job.arguments.first.class.inspect
41
+ assert_equal 'value', @job.arguments.first['key']
42
+ assert_equal 'value', @job.arguments.first[:key]
43
+ end
44
+ end
45
+
46
+ context '#save!' do
47
+ should 'save a blank job' do
48
+ @job.save!
49
+ assert_nil @job.server_name
50
+ assert_nil @job.completed_at
51
+ assert @job.created_at
52
+ assert_equal @description, @job.description
53
+ assert_equal false, @job.destroy_on_complete
54
+ assert_nil @job.expires_at
55
+ assert_equal @arguments, @job.arguments
56
+ assert_equal 0, @job.percent_complete
57
+ assert_equal 50, @job.priority
58
+ assert_equal true, @job.repeatable
59
+ assert_equal 0, @job.failure_count
60
+ assert_nil @job.run_at
61
+ assert_nil @job.schedule
62
+ assert_nil @job.started_at
63
+ assert_equal :queued, @job.state
64
+ end
65
+ end
66
+
67
+ context '#status' do
68
+ should 'return status for a queued job' do
69
+ assert_equal true, @job.queued?
70
+ h = @job.status
71
+ assert_equal :queued, h[:state]
72
+ assert_equal @description, h[:description]
73
+ end
74
+
75
+ should 'return status for a failed job' do
76
+ @job.build_exception(
77
+ class_name: 'Test',
78
+ message: 'hello world'
79
+ )
80
+ @job.start!
81
+ @job.fail!
82
+ assert_equal true, @job.failed?
83
+ h = @job.status
84
+ assert_equal :failed, h[:state]
85
+ assert_equal @description, h[:description]
86
+ assert_equal 'Test', h[:exception][:class_name], h
87
+ assert_equal 'hello world', h[:exception][:message], h
88
+ end
89
+ end
90
+
91
+ context '#work' do
92
+ should 'call default perform method' do
93
+ @job.start!
94
+ assert_equal false, @job.work(@server)
95
+ assert_equal true, @job.completed?, @job.state
96
+ assert_equal 2, Jobs::TestJob.result
97
+ end
98
+
99
+ should 'call specific method' do
100
+ @job.perform_method = :sum
101
+ @job.arguments = [ 23, 45 ]
102
+ @job.start!
103
+ assert_equal false, @job.work(@server)
104
+ assert_equal true, @job.completed?
105
+ assert_equal 68, Jobs::TestJob.result
106
+ end
107
+
108
+ should 'destroy on complete' do
109
+ @job.destroy_on_complete = true
110
+ @job.start!
111
+ assert_equal false, @job.work(@server)
112
+ assert_equal nil, RocketJob::Job.find_by_id(@job.id)
113
+ end
114
+
115
+ should 'silence logging when log_level is set' do
116
+ @job.destroy_on_complete = true
117
+ @job.log_level = :warn
118
+ @job.perform_method = :noisy_logger
119
+ @job.arguments = []
120
+ @job.start!
121
+ logged = false
122
+ Jobs::TestJob.logger.stub(:log_internal, -> level, index, message, payload, exception { logged = true if message.include?('some very noisy logging')}) do
123
+ assert_equal false, @job.work(@server), @job.inspect
124
+ end
125
+ assert_equal false, logged
126
+ end
127
+
128
+ should 'raise logging when log_level is set' do
129
+ @job.destroy_on_complete = true
130
+ @job.log_level = :trace
131
+ @job.perform_method = :debug_logging
132
+ @job.arguments = []
133
+ @job.start!
134
+ logged = false
135
+ # Raise global log level to :info
136
+ SemanticLogger.stub(:default_level_index, 3) do
137
+ Jobs::TestJob.logger.stub(:log_internal, -> { logged = true }) do
138
+ assert_equal false, @job.work(@server)
139
+ end
140
+ end
141
+ assert_equal false, logged
142
+ end
143
+
144
+ should 'call before and after' do
145
+ named_parameters = { 'counter' => 23 }
146
+ @job.perform_method = :event
147
+ @job.arguments = [ named_parameters ]
148
+ @job.start!
149
+ assert_equal false, @job.work(@server), @job.inspect
150
+ assert_equal true, @job.completed?
151
+ assert_equal named_parameters.merge('before_event' => true, 'after_event' => true), @job.arguments.first
152
+ end
153
+
154
+ end
155
+
156
+ context '.next_job' do
157
+ setup do
158
+ RocketJob::Job.destroy_all
159
+ end
160
+
161
+ should 'return nil when no jobs available' do
162
+ assert_equal nil, RocketJob::Job.next_job(@server.name)
163
+ end
164
+
165
+ should 'return the first job' do
166
+ @job.save!
167
+ assert job = RocketJob::Job.next_job(@server.name), "Failed to find job"
168
+ assert_equal @job.id, job.id
169
+ end
170
+
171
+ should 'Ignore future dated jobs' do
172
+ @job.run_at = Time.now + 1.hour
173
+ @job.save!
174
+ assert_equal nil, RocketJob::Job.next_job(@server.name)
175
+ end
176
+
177
+ should 'Process future dated jobs when time is now' do
178
+ @job.run_at = Time.now
179
+ @job.save!
180
+ assert job = RocketJob::Job.next_job(@server.name), "Failed to find future job"
181
+ assert_equal @job.id, job.id
182
+ end
183
+
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,42 @@
1
+ require 'rocketjob'
2
+ module Jobs
3
+ class TestJob < RocketJob::Job
4
+ @@result = nil
5
+
6
+ # For holding test results
7
+ def self.result
8
+ @@result
9
+ end
10
+
11
+ def perform(first)
12
+ @@result = first + 1
13
+ end
14
+
15
+ def sum(a, b)
16
+ @@result = a + b
17
+ end
18
+
19
+ # Test silencing noisy logging
20
+ def noisy_logger
21
+ logger.info 'some very noisy logging'
22
+ end
23
+
24
+ # Test increasing log level for debugging purposes
25
+ def debug_logging
26
+ logger.trace 'enable tracing level for just the job instance'
27
+ end
28
+
29
+ def before_event(hash)
30
+ hash['before_event'] = true
31
+ end
32
+
33
+ def event(hash)
34
+ hash['event'] = true
35
+ end
36
+
37
+ def after_event(hash)
38
+ hash['after_event'] = true
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'test_helper'
2
+ require_relative 'jobs/test_job'
3
+
4
+ # Unit Test for RocketJob::Server
5
+ class ServerTest < Minitest::Test
6
+ context RocketJob::Server do
7
+ setup do
8
+ RocketJob::Config.instance.heartbeat_seconds = 0.1
9
+ RocketJob::Config.instance.max_poll_seconds = 0.1
10
+ @server = RocketJob::Server.new
11
+ @description = 'Hello World'
12
+ @arguments = [ 1 ]
13
+ @job = Jobs::TestJob.new(
14
+ description: @description,
15
+ arguments: @arguments,
16
+ destroy_on_complete: false
17
+ )
18
+ end
19
+
20
+ teardown do
21
+ @job.destroy if @job && !@job.new_record?
22
+ end
23
+
24
+ context '.config' do
25
+ should 'support multiple databases' do
26
+ assert_equal 'test_rocket_job', RocketJob::Job.collection.db.name
27
+ end
28
+ end
29
+
30
+ context '#run' do
31
+ should 'run a server' do
32
+ Thread.new { sleep 1; @server.stop!}
33
+ @server.run
34
+ assert_equal :stopping, @server.state, @server.inspect
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'yaml'
4
+ require 'minitest/autorun'
5
+ require 'minitest/reporters'
6
+ require 'minitest/stub_any_instance'
7
+ require 'shoulda/context'
8
+ require 'rocketjob'
9
+ require 'awesome_print'
10
+ require 'symmetric-encryption'
11
+
12
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
13
+
14
+ SemanticLogger.add_appender('test.log', &SemanticLogger::Appender::Base.colorized_formatter)
15
+ SemanticLogger.default_level = :debug
16
+
17
+ # Setup MongoMapper from mongo config file
18
+ config_file = File.join(File.dirname(__FILE__), 'config', 'mongo.yml')
19
+ if config = YAML.load(ERB.new(File.read(config_file)).result)
20
+ cfg = config['test']
21
+ options = cfg['options'] || {}
22
+ options[:logger] = SemanticLogger::DebugAsTraceLogger.new('Mongo')
23
+
24
+ MongoMapper.config = cfg
25
+ MongoMapper.connection = Mongo::MongoClient.from_uri(cfg['uri'], options)
26
+ MongoMapper.database = MongoMapper.connection.db.name
27
+
28
+ # If this environment has a separate Work server
29
+ if cfg = config['test_work']
30
+ options = cfg['options'] || {}
31
+ options[:logger] = SemanticLogger::DebugAsTraceLogger.new('MongoWork')
32
+ RocketJob::Config.mongo_work_connection = Mongo::MongoClient.from_uri(cfg['uri'], options)
33
+ end
34
+ end
35
+
36
+ # Test cipher
37
+ SymmetricEncryption.cipher = SymmetricEncryption::Cipher.new(
38
+ cipher_name: 'aes-128-cbc',
39
+ key: '1234567890ABCDEF1234567890ABCDEF',
40
+ iv: '1234567890ABCDEF',
41
+ encoding: :base64strict
42
+ )
43
+
@@ -0,0 +1,89 @@
1
+ require_relative 'test_helper'
2
+ require_relative 'jobs/test_job'
3
+
4
+ # Unit Test for RocketJob::Job
5
+ class WorkerTest < Minitest::Test
6
+ context RocketJob::Job do
7
+ [true, false].each do |inline_mode|
8
+ setup do
9
+ RocketJob::Config.inline_mode = inline_mode
10
+ @server = RocketJob::Server.new
11
+ @server.started
12
+ end
13
+
14
+ teardown do
15
+ @job.destroy if @job && !@job.new_record?
16
+ RocketJob::Config.inline_mode = false
17
+ end
18
+
19
+ context '.perform_later' do
20
+ should "process single request (inline_mode=#{inline_mode})" do
21
+ @job = Jobs::TestJob.perform_later(1) do |job|
22
+ job.destroy_on_complete = false
23
+ end
24
+ assert_nil @job.server_name
25
+ assert_nil @job.completed_at
26
+ assert @job.created_at
27
+ assert_nil @job.description
28
+ assert_equal false, @job.destroy_on_complete
29
+ assert_nil @job.expires_at
30
+ assert_equal 0, @job.percent_complete
31
+ assert_equal 50, @job.priority
32
+ assert_equal true, @job.repeatable
33
+ assert_equal 0, @job.failure_count
34
+ assert_nil @job.run_at
35
+ assert_nil @job.schedule
36
+ assert_nil @job.started_at
37
+ assert_equal :queued, @job.state
38
+
39
+ @job.server_name = 'me'
40
+ @job.start
41
+ assert_equal false, @job.work(@server), @job.exception.inspect
42
+ assert_equal true, @job.completed?
43
+ assert_equal 2, Jobs::TestJob.result
44
+
45
+ assert @job.server_name
46
+ assert @job.completed_at
47
+ assert @job.created_at
48
+ assert_nil @job.description
49
+ assert_equal false, @job.destroy_on_complete
50
+ assert_nil @job.expires_at
51
+ assert_equal 100, @job.percent_complete
52
+ assert_equal 50, @job.priority
53
+ assert_equal true, @job.repeatable
54
+ assert_equal 0, @job.failure_count
55
+ assert_nil @job.run_at
56
+ assert_nil @job.schedule
57
+ assert @job.started_at
58
+ end
59
+ end
60
+
61
+ context '.later' do
62
+ should "process non default method (inline_mode=#{inline_mode})" do
63
+ @job = Jobs::TestJob.later(:sum, 23, 45)
64
+ @job.start
65
+ assert_equal false, @job.work(@server), @job.exception.inspect
66
+ assert_equal true, @job.completed?
67
+ assert_equal 68, Jobs::TestJob.result
68
+ end
69
+ end
70
+
71
+ context '.perform_now' do
72
+ should "process perform (inline_mode=#{inline_mode})" do
73
+ @job = Jobs::TestJob.perform_now(5)
74
+ assert_equal true, @job.completed?
75
+ assert_equal 6, Jobs::TestJob.result
76
+ end
77
+ end
78
+
79
+ context '.now' do
80
+ should "process non default method (inline_mode=#{inline_mode})" do
81
+ @job = Jobs::TestJob.now(:sum, 23, 45)
82
+ assert_equal true, @job.completed?, @job.inspect
83
+ assert_equal 68, Jobs::TestJob.result
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rocketjob
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ platform: ruby
6
+ authors:
7
+ - Reid Morrison
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aasm
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: semantic_logger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.13'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mongo_ha
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.11'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mongo
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mongo_mapper
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.13'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.13'
83
+ - !ruby/object:Gem::Dependency
84
+ name: symmetric-encryption
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sync_attr
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ description: Designed for batch processing from single records to millions of records
112
+ in a single batch. Uses threading instead of process forking for greater throughtput.
113
+ email:
114
+ - reidmo@gmail.com
115
+ executables:
116
+ - rocketjob
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - README.md
121
+ - Rakefile
122
+ - bin/rocketjob
123
+ - lib/rocket_job/cli.rb
124
+ - lib/rocket_job/concerns/worker.rb
125
+ - lib/rocket_job/config.rb
126
+ - lib/rocket_job/heartbeat.rb
127
+ - lib/rocket_job/job.rb
128
+ - lib/rocket_job/job_exception.rb
129
+ - lib/rocket_job/server.rb
130
+ - lib/rocket_job/version.rb
131
+ - lib/rocketjob.rb
132
+ - test/config/mongo.yml
133
+ - test/job_test.rb
134
+ - test/jobs/test_job.rb
135
+ - test/server_test.rb
136
+ - test/test_helper.rb
137
+ - test/worker_test.rb
138
+ homepage: https://github.com/rocketjob/rocketjob
139
+ licenses:
140
+ - GPL-3.0
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.4.8
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: High volume, priority based, Enterprise Batch Processing solution for Ruby
162
+ test_files:
163
+ - test/config/mongo.yml
164
+ - test/job_test.rb
165
+ - test/jobs/test_job.rb
166
+ - test/server_test.rb
167
+ - test/test_helper.rb
168
+ - test/worker_test.rb