robot_sweatshop 0.4.12 → 0.4.13
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/bin/sweatshop +1 -1
- data/bin/sweatshop-api +2 -1
- data/bin/sweatshop-assembler +8 -6
- data/bin/sweatshop-conveyor +16 -11
- data/bin/sweatshop-job-dictionary +13 -8
- data/bin/sweatshop-logger +32 -0
- data/bin/sweatshop-overseer +0 -1
- data/bin/sweatshop-payload-parser +11 -6
- data/bin/sweatshop-worker +14 -13
- data/config.defaults.yaml +2 -0
- data/lib/robot_sweatshop/connections.rb +26 -0
- data/robot_sweatshop.eye +5 -8
- data/robot_sweatshop.gemspec +1 -1
- data/test/all.rb +1 -0
- data/test/logger_spec.rb +36 -0
- data/test/overseer_spec.rb +5 -5
- data/test/shared/helpers/input.rb +2 -2
- data/test/shared/scaffolding.rb +2 -1
- data/test/shared/stub.rb +2 -0
- data/test/worker_spec.rb +13 -13
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 08cbf83ffc230f92b481c9bd3e050e30c8b2a771
|
4
|
+
data.tar.gz: 3945c41f5f694828ad9651c18e6e8d33e761f0b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0c61a1c671dd53bf48c3aa723cc78b41266817492bc49312d2bdc1cb216491c2f2b597e83659e1ee9479519af92de3d3c207a60f536cd5f8dcebdaf04899195
|
7
|
+
data.tar.gz: 10fa29c67fc744705d541c7846bda2882529c7cf79279838e6c3028ba6795f6cecba7633d5d390efda31483a7db5dcaa5b16515bb18319a331575f871027b27b
|
data/Gemfile.lock
CHANGED
data/bin/sweatshop
CHANGED
@@ -7,7 +7,7 @@ require 'robot_sweatshop/config'
|
|
7
7
|
require 'robot_sweatshop/create-config-directories'
|
8
8
|
|
9
9
|
program :name, 'Robot Sweatshop'
|
10
|
-
program :version, '0.4.
|
10
|
+
program :version, '0.4.13'
|
11
11
|
program :description, 'A lightweight, nonopinionated CI server'
|
12
12
|
program :help, 'Author', 'Justin Scott <jvscott@gmail.com>'
|
13
13
|
|
data/bin/sweatshop-api
CHANGED
@@ -10,6 +10,7 @@ configure do
|
|
10
10
|
set :port, configatron.api_port
|
11
11
|
set :bind, configatron.http_bind
|
12
12
|
set :run, true
|
13
|
+
set :log, EZMQ::Logger.new('api')
|
13
14
|
set :conveyor, EZMQ::Client.new(port: configatron.conveyor_port)
|
14
15
|
settings.conveyor.serialize_with_json!
|
15
16
|
enable :cross_origin if configatron.http_cross_origin
|
@@ -20,7 +21,7 @@ get '/' do
|
|
20
21
|
end
|
21
22
|
|
22
23
|
post '/run/:job_name' do
|
23
|
-
|
24
|
+
settings.log.write "Received payload for #{params['job_name']}"
|
24
25
|
request.body.rewind
|
25
26
|
payload = request.body.read
|
26
27
|
hash = {
|
data/bin/sweatshop-assembler
CHANGED
@@ -5,7 +5,6 @@ require 'exponential_backoff'
|
|
5
5
|
require 'ezmq'
|
6
6
|
require 'robot_sweatshop/config'
|
7
7
|
require 'robot_sweatshop/connections'
|
8
|
-
$stdout.sync = true
|
9
8
|
include Contracts
|
10
9
|
using ExtendedEZMQ
|
11
10
|
|
@@ -45,7 +44,7 @@ def request_job
|
|
45
44
|
job_id = @sockets[:conveyor].request method: 'dequeue'
|
46
45
|
return nil if job_id.nil?
|
47
46
|
raw_job = @sockets[:conveyor].request method: 'lookup', data: job_id
|
48
|
-
|
47
|
+
@sockets[:logger].write "Assembling: '#{raw_job}'"
|
49
48
|
raw_job.merge job_id: job_id
|
50
49
|
end
|
51
50
|
|
@@ -87,15 +86,18 @@ job_search = Fiber.new do
|
|
87
86
|
end
|
88
87
|
end
|
89
88
|
|
90
|
-
puts 'Started'
|
91
89
|
@sockets = {
|
92
90
|
conveyor: EZMQ::Client.new(port: configatron.conveyor_port),
|
93
91
|
worker: EZMQ::Pusher.new(:bind, port: configatron.worker_port),
|
94
92
|
parser: EZMQ::Client.new(port: configatron.payload_parser_port),
|
95
|
-
dictionary: EZMQ::Client.new(port: configatron.job_dictionary_port)
|
93
|
+
dictionary: EZMQ::Client.new(port: configatron.job_dictionary_port),
|
94
|
+
logger: EZMQ::Logger.new('assembler')
|
96
95
|
}
|
97
|
-
@sockets.each
|
96
|
+
@sockets.each do |key, socket|
|
97
|
+
socket.serialize_with_json! unless key == :logger
|
98
|
+
end
|
98
99
|
|
100
|
+
@sockets[:logger].write 'Started'
|
99
101
|
loop do
|
100
102
|
job = job_search.resume
|
101
103
|
begin
|
@@ -104,7 +106,7 @@ loop do
|
|
104
106
|
assembled_job = assemble job, payload, definition
|
105
107
|
@sockets[:worker].send assembled_job
|
106
108
|
rescue RuntimeError => error
|
107
|
-
|
109
|
+
@sockets[:logger].write error.message
|
108
110
|
finish job[:job_id]
|
109
111
|
next
|
110
112
|
end
|
data/bin/sweatshop-conveyor
CHANGED
@@ -5,6 +5,7 @@ require 'contracts'
|
|
5
5
|
require 'robot_sweatshop/config'
|
6
6
|
require 'robot_sweatshop/connections'
|
7
7
|
using ExtendedEZMQ
|
8
|
+
include Contracts
|
8
9
|
|
9
10
|
queue_settings = {
|
10
11
|
name: 'test',
|
@@ -12,30 +13,28 @@ queue_settings = {
|
|
12
13
|
file: "#{configatron.database_path}/conveyor.db"
|
13
14
|
}
|
14
15
|
@items = StubbornQueue.new queue_settings
|
15
|
-
$stdout.sync = true
|
16
|
-
include Contracts
|
17
16
|
|
18
17
|
Contract Hash => Fixnum
|
19
18
|
def enqueue(item)
|
20
|
-
|
19
|
+
@sockets[:logger].write "enqueue #{item}"
|
21
20
|
@items.enqueue item
|
22
21
|
end
|
23
22
|
|
24
23
|
Contract None => Maybe[Fixnum]
|
25
24
|
def dequeue
|
26
|
-
|
25
|
+
@sockets[:logger].write 'dequeue'
|
27
26
|
@items.dequeue
|
28
27
|
end
|
29
28
|
|
30
29
|
Contract Fixnum => Hash
|
31
30
|
def lookup(id)
|
32
|
-
|
31
|
+
@sockets[:logger].write "lookup #{id}"
|
33
32
|
@items.lookup(id)
|
34
33
|
end
|
35
34
|
|
36
35
|
Contract Fixnum => Bool
|
37
36
|
def finish(id)
|
38
|
-
|
37
|
+
@sockets[:logger].write "finish #{id}"
|
39
38
|
@items.finish id
|
40
39
|
end
|
41
40
|
|
@@ -50,11 +49,17 @@ def complete(request)
|
|
50
49
|
send(request[:method])
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
server
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
@sockets = {
|
53
|
+
server: EZMQ::Server.new(port: configatron.conveyor_port),
|
54
|
+
logger: EZMQ::Logger.new('conveyor')
|
55
|
+
}
|
56
|
+
@sockets.each do |key, socket|
|
57
|
+
socket.serialize_with_json! unless key == :logger
|
58
|
+
end
|
59
|
+
|
60
|
+
@sockets[:logger].write 'Started'
|
61
|
+
@sockets[:server].listen do |request|
|
62
|
+
@sockets[:logger].write "Received: #{request.inspect}"
|
58
63
|
next unless request.is_a? Hash
|
59
64
|
next unless supported? request[:method]
|
60
65
|
complete request
|
@@ -4,7 +4,6 @@ require 'ezmq'
|
|
4
4
|
require 'contracts'
|
5
5
|
require 'robot_sweatshop/config'
|
6
6
|
require 'robot_sweatshop/connections'
|
7
|
-
$stdout.sync = true
|
8
7
|
include Contracts
|
9
8
|
using ExtendedEZMQ
|
10
9
|
|
@@ -15,13 +14,13 @@ end
|
|
15
14
|
|
16
15
|
Contract String => Or[Hash, nil]
|
17
16
|
def load_if_exists(config_path)
|
18
|
-
|
17
|
+
@sockets[:logger].write "Reading job configuration from #{config_path}"
|
19
18
|
YAML.load_file config_path if File.exist? config_path
|
20
19
|
end
|
21
20
|
|
22
21
|
Contract None => Hash
|
23
22
|
def empty_config
|
24
|
-
|
23
|
+
@sockets[:logger].write 'Job configuration not found or empty'
|
25
24
|
{}
|
26
25
|
end
|
27
26
|
|
@@ -43,10 +42,16 @@ def define(job_name)
|
|
43
42
|
formatted config
|
44
43
|
end
|
45
44
|
|
46
|
-
|
47
|
-
server
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
@sockets = {
|
46
|
+
server: EZMQ::Server.new(port: configatron.job_dictionary_port),
|
47
|
+
logger: EZMQ::Logger.new('job_dictionary')
|
48
|
+
}
|
49
|
+
@sockets.each do |key, socket|
|
50
|
+
socket.serialize_with_json! unless key == :logger
|
51
|
+
end
|
52
|
+
|
53
|
+
@sockets[:logger].write 'Started'
|
54
|
+
@sockets[:server].listen do |job_name|
|
55
|
+
@sockets[:logger].write "Looking up: #{job_name}"
|
51
56
|
define job_name
|
52
57
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'ezmq'
|
3
|
+
require 'robot_sweatshop/config'
|
4
|
+
require 'robot_sweatshop/connections'
|
5
|
+
using ExtendedEZMQ
|
6
|
+
|
7
|
+
@sockets = {
|
8
|
+
subscriber: EZMQ::Subscriber.new(:bind, port: configatron.logger_port, topic: 'robot-sweatshop-logging'),
|
9
|
+
reflector: EZMQ::Publisher.new(:bind, port: configatron.reflector_port)
|
10
|
+
}
|
11
|
+
@sockets.each do |key, socket|
|
12
|
+
socket.serialize_with_json! unless key == :logger
|
13
|
+
end
|
14
|
+
|
15
|
+
def write(text, for_process:)
|
16
|
+
log_file = File.expand_path "#{configatron.logfile_path}/#{for_process}.log"
|
17
|
+
File.open log_file, 'a' do |log|
|
18
|
+
log.write "[#{Time.now.utc}] #{text}\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_worker_id_from(data)
|
23
|
+
process, worker_id = data[:process].split '-'
|
24
|
+
data.merge process: process, text: "[#{worker_id}] #{data[:text]}"
|
25
|
+
end
|
26
|
+
|
27
|
+
write 'Started', for_process: 'logger'
|
28
|
+
@sockets[:subscriber].listen do |data, topic|
|
29
|
+
data = parse_worker_id_from data if data[:process] =~ /worker/
|
30
|
+
write data[:text], for_process: data[:process]
|
31
|
+
@sockets[:reflector].send data, topic: topic
|
32
|
+
end
|
data/bin/sweatshop-overseer
CHANGED
@@ -5,7 +5,6 @@ require 'contracts'
|
|
5
5
|
require 'robot_sweatshop/config'
|
6
6
|
require 'robot_sweatshop/payload'
|
7
7
|
require 'robot_sweatshop/connections'
|
8
|
-
$stdout.sync = true
|
9
8
|
include Contracts
|
10
9
|
using ExtendedEZMQ
|
11
10
|
|
@@ -57,11 +56,17 @@ def parse(raw_payload, format)
|
|
57
56
|
formatted payload
|
58
57
|
end
|
59
58
|
|
60
|
-
|
61
|
-
server
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
@sockets = {
|
60
|
+
server: EZMQ::Server.new(port: configatron.payload_parser_port),
|
61
|
+
logger: EZMQ::Logger.new('payload_parser')
|
62
|
+
}
|
63
|
+
@sockets.each do |key, socket|
|
64
|
+
socket.serialize_with_json! unless key == :logger
|
65
|
+
end
|
66
|
+
|
67
|
+
@sockets[:logger].write 'Started'
|
68
|
+
@sockets[:server].listen do |request|
|
69
|
+
@sockets[:logger].write "Parsing: #{request}"
|
65
70
|
format = detect_format_of request
|
66
71
|
parse request[:payload], format
|
67
72
|
end
|
data/bin/sweatshop-worker
CHANGED
@@ -5,10 +5,8 @@ require 'fileutils'
|
|
5
5
|
require 'contracts'
|
6
6
|
require 'robot_sweatshop/config'
|
7
7
|
require 'robot_sweatshop/connections'
|
8
|
-
using ExtendedEZMQ
|
9
|
-
$stdout.sync = true
|
10
|
-
$stderr.sync = true
|
11
8
|
include Contracts
|
9
|
+
using ExtendedEZMQ
|
12
10
|
|
13
11
|
# TODO: check existing worker ids. it'd be a problem to share a workspace
|
14
12
|
@worker_id = ARGV[0] || "#{Faker::Name.first_name}"
|
@@ -16,7 +14,7 @@ include Contracts
|
|
16
14
|
Contract Hash, Proc => Any
|
17
15
|
def from_workspace(named:)
|
18
16
|
workspace = "#{named}-#{@worker_id}"
|
19
|
-
|
17
|
+
@sockets[:logger].write "Workspace: #{workspace}"
|
20
18
|
path = File.expand_path "#{configatron.workspace_path}/#{workspace}"
|
21
19
|
FileUtils.mkpath path
|
22
20
|
Dir.chdir(path) { yield if block_given? }
|
@@ -31,25 +29,25 @@ Contract String, Hash => Maybe[IO]
|
|
31
29
|
def stream(command, with_context:)
|
32
30
|
command = ensure_shell_for command
|
33
31
|
IO.popen(with_context, command) do |stream|
|
34
|
-
|
32
|
+
@sockets[:logger].write stream.gets until stream.eof?
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
36
|
Contract String, Hash => nil
|
39
37
|
def execute(command, context)
|
40
|
-
|
38
|
+
@sockets[:logger].write "Executing '#{command}'"
|
41
39
|
begin
|
42
40
|
stream command, with_context: context
|
43
41
|
rescue Errno::ENOENT => error
|
44
|
-
|
42
|
+
@sockets[:logger].write error.message
|
45
43
|
end
|
46
|
-
|
44
|
+
@sockets[:logger].write "Execution complete with exit status: #{$?.exitstatus}"
|
47
45
|
end
|
48
46
|
|
49
47
|
Contract Fixnum => nil
|
50
48
|
def finish(id)
|
51
49
|
@sockets[:conveyor].request({ method: 'finish', data: id }, {})
|
52
|
-
|
50
|
+
@sockets[:logger].write "Job finished.\n\n"
|
53
51
|
end
|
54
52
|
|
55
53
|
Contract Array, Hash => Any
|
@@ -65,15 +63,18 @@ def run_implicit_job
|
|
65
63
|
run implicit_job['commands'], with_context: implicit_job['environment']
|
66
64
|
end
|
67
65
|
|
68
|
-
puts 'Starting'
|
69
66
|
@sockets = {
|
70
67
|
conveyor: EZMQ::Client.new(port: configatron.conveyor_port),
|
71
|
-
puller: EZMQ::Puller.new(:connect, port: configatron.worker_port)
|
68
|
+
puller: EZMQ::Puller.new(:connect, port: configatron.worker_port),
|
69
|
+
logger: EZMQ::Logger.new("worker-#{@worker_id}")
|
72
70
|
}
|
73
|
-
@sockets.each
|
71
|
+
@sockets.each do |key, socket|
|
72
|
+
socket.serialize_with_json! unless key == :logger
|
73
|
+
end
|
74
74
|
|
75
|
+
@sockets[:logger].write 'Started'
|
75
76
|
@sockets[:puller].listen do |data|
|
76
|
-
|
77
|
+
@sockets[:logger].write "Running: #{data}"
|
77
78
|
from_workspace named: data[:job_name] do
|
78
79
|
run data[:commands], with_context: data[:context]
|
79
80
|
run_implicit_job
|
data/config.defaults.yaml
CHANGED
@@ -16,3 +16,29 @@ module ExtendedEZMQ
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
|
+
|
20
|
+
# A logger that publishes what it writes
|
21
|
+
module EZMQ
|
22
|
+
class Logger
|
23
|
+
using ExtendedEZMQ
|
24
|
+
|
25
|
+
def initialize(process)
|
26
|
+
@process = process
|
27
|
+
@logger = EZMQ::Publisher.new :connect, port: configatron.logger_port
|
28
|
+
@logger.serialize_with_json!
|
29
|
+
@user = `whoami`.chomp
|
30
|
+
@host = `hostname`.chomp
|
31
|
+
end
|
32
|
+
|
33
|
+
def write(text)
|
34
|
+
data = {
|
35
|
+
text: text,
|
36
|
+
process: @process,
|
37
|
+
user: @user,
|
38
|
+
host: @host
|
39
|
+
}
|
40
|
+
@logger.send data, topic: 'robot-sweatshop-logging'
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/robot_sweatshop.eye
CHANGED
@@ -4,7 +4,6 @@ require 'yaml'
|
|
4
4
|
CONFIG_PATH = File.expand_path '~/.robot_sweatshop/compiled_config.yaml'
|
5
5
|
CONFIG = YAML.load_file CONFIG_PATH
|
6
6
|
PID_PATH = CONFIG[:pidfile_path]
|
7
|
-
LOG_PATH = CONFIG[:logfile_path]
|
8
7
|
|
9
8
|
Eye.config do
|
10
9
|
logger "#{CONFIG[:logfile_path]}/eye.log"
|
@@ -18,19 +17,16 @@ Eye.application :robot_sweatshop do
|
|
18
17
|
group 'services' do
|
19
18
|
process :job_dictionary do
|
20
19
|
pid_file "#{PID_PATH}/job-dictionary.pid"
|
21
|
-
stdall "#{LOG_PATH}/job-dictionary.log"
|
22
20
|
start_command "#{__dir__}/bin/sweatshop-job-dictionary"
|
23
21
|
daemonize true
|
24
22
|
end
|
25
23
|
process :payload_parser do
|
26
24
|
pid_file "#{PID_PATH}/payload-parser.pid"
|
27
|
-
stdall "#{LOG_PATH}/payload-parser.log"
|
28
25
|
start_command "#{__dir__}/bin/sweatshop-payload-parser"
|
29
26
|
daemonize true
|
30
27
|
end
|
31
28
|
process :conveyor do
|
32
29
|
pid_file "#{PID_PATH}/conveyor.pid"
|
33
|
-
stdall "#{LOG_PATH}/conveyor.log"
|
34
30
|
start_command "#{__dir__}/bin/sweatshop-conveyor"
|
35
31
|
daemonize true
|
36
32
|
end
|
@@ -38,26 +34,27 @@ Eye.application :robot_sweatshop do
|
|
38
34
|
|
39
35
|
process :overseer do
|
40
36
|
pid_file "#{PID_PATH}/overseer.pid"
|
41
|
-
stdall "#{LOG_PATH}/overseer.log"
|
42
37
|
start_command "#{__dir__}/bin/sweatshop-overseer"
|
43
38
|
daemonize true
|
44
39
|
end
|
45
40
|
process :api do
|
46
41
|
pid_file "#{PID_PATH}/api.pid"
|
47
|
-
stdall "#{LOG_PATH}/api.log"
|
48
42
|
start_command "#{__dir__}/bin/sweatshop-api"
|
49
43
|
daemonize true
|
50
44
|
end
|
51
45
|
process :assembler do
|
52
46
|
pid_file "#{PID_PATH}/assembler.pid"
|
53
|
-
stdall "#{LOG_PATH}/assembler.log"
|
54
47
|
start_command "#{__dir__}/bin/sweatshop-assembler"
|
55
48
|
daemonize true
|
56
49
|
end
|
57
50
|
process :worker do
|
58
51
|
pid_file "#{PID_PATH}/worker.pid"
|
59
|
-
stdall "#{LOG_PATH}/worker.log"
|
60
52
|
start_command "#{__dir__}/bin/sweatshop-worker"
|
61
53
|
daemonize true
|
62
54
|
end
|
55
|
+
process :logger do
|
56
|
+
pid_file "#{PID_PATH}/logger.pid"
|
57
|
+
start_command "#{__dir__}/bin/sweatshop-logger"
|
58
|
+
daemonize true
|
59
|
+
end
|
63
60
|
end
|
data/robot_sweatshop.gemspec
CHANGED
data/test/all.rb
CHANGED
data/test/logger_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'kintama'
|
2
|
+
require 'ezmq'
|
3
|
+
require 'timeout'
|
4
|
+
require 'robot_sweatshop/config'
|
5
|
+
require 'robot_sweatshop/connections'
|
6
|
+
require_relative 'shared/scaffolding'
|
7
|
+
require_relative 'shared/helpers'
|
8
|
+
|
9
|
+
Kintama.on_start do
|
10
|
+
@pids = TestProcess.start %w(logger)
|
11
|
+
end
|
12
|
+
|
13
|
+
Kintama.on_finish do
|
14
|
+
TestProcess.stop @pids
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'the Logger' do
|
18
|
+
given 'log data from a process' do
|
19
|
+
setup do
|
20
|
+
@custom_logger = TestProcess.stub :logger
|
21
|
+
EZMQ::Logger.new('test_spec').write 'success'
|
22
|
+
sleep $a_while # TODO: Timeout wasn't working for some reason
|
23
|
+
# Also breaks if this is in the `should` block :S
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'log the data to file' do
|
27
|
+
log_file = File.expand_path "#{configatron.logfile_path}/test_spec.log"
|
28
|
+
assert_match /success/, File.read(log_file)
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'reflect the published message' do
|
32
|
+
reflection = File.read @custom_logger.output_file
|
33
|
+
assert_match /success/, reflection
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/test/overseer_spec.rb
CHANGED
@@ -7,7 +7,7 @@ require_relative 'shared/helpers'
|
|
7
7
|
$stdout.sync = true
|
8
8
|
|
9
9
|
Kintama.on_start do
|
10
|
-
@pids = TestProcess.start %w(overseer)
|
10
|
+
@pids = TestProcess.start %w(overseer logger)
|
11
11
|
sleep $a_while
|
12
12
|
end
|
13
13
|
|
@@ -23,7 +23,7 @@ given 'the Overseer' do
|
|
23
23
|
should('respond') { assert_equal 200, @response.code }
|
24
24
|
should('link to process logs') do
|
25
25
|
page = Nokogiri::HTML(@response.to_s)
|
26
|
-
links = page.css('a').select { |link| link.text.include? '
|
26
|
+
links = page.css('a').select { |link| link.text.include? 'logger' }
|
27
27
|
assert_not_equal 0, links.count
|
28
28
|
end
|
29
29
|
should('have a form for running jobs') do
|
@@ -36,12 +36,12 @@ given 'the Overseer' do
|
|
36
36
|
setup { Timeout.timeout($a_while) { @response = HTTP.get overseer_url('log') } }
|
37
37
|
should('redirect') { assert_equal 303, @response.code }
|
38
38
|
end
|
39
|
-
context '/log?for=
|
40
|
-
setup { Timeout.timeout($a_while) { @response = HTTP.get overseer_url('log?for=
|
39
|
+
context '/log?for=logger' do
|
40
|
+
setup { Timeout.timeout($a_while) { @response = HTTP.get overseer_url('log?for=logger') } }
|
41
41
|
should('respond') { assert_equal 200, @response.code }
|
42
42
|
should('show logs from file') do
|
43
43
|
page = Nokogiri::HTML(@response.to_s)
|
44
|
-
log = File.read "#{configatron.logfile_path}/
|
44
|
+
log = File.read "#{configatron.logfile_path}/logger.log"
|
45
45
|
output = page.css('.raw_log').first
|
46
46
|
assert_equal log, output.text, 'Expected raw log output'
|
47
47
|
end
|
data/test/shared/scaffolding.rb
CHANGED
@@ -41,7 +41,8 @@ module TestProcess
|
|
41
41
|
def self.stub(process_name)
|
42
42
|
process = {
|
43
43
|
conveyor: {type: 'Server', port: configatron.conveyor_port},
|
44
|
-
worker: {type: 'Puller', port: configatron.worker_port}
|
44
|
+
worker: {type: 'Puller', port: configatron.worker_port},
|
45
|
+
logger: {type: 'Subscriber', port: configatron.reflector_port}
|
45
46
|
}[process_name]
|
46
47
|
Stub.new process[:type], on_port: process[:port]
|
47
48
|
end
|
data/test/shared/stub.rb
CHANGED
data/test/worker_spec.rb
CHANGED
@@ -24,9 +24,13 @@ describe 'the Worker' do
|
|
24
24
|
|
25
25
|
setup do
|
26
26
|
@conveyor = TestProcess.stub :conveyor
|
27
|
+
@workspace_file = "#{configatron.workspace_path}/test_job-testingid/test.txt"
|
27
28
|
@pusher = EZMQ::Pusher.new :bind, port: configatron.worker_port
|
28
29
|
@pusher.serialize_with_json!
|
29
|
-
|
30
|
+
@pusher.send worker_push
|
31
|
+
Timeout.timeout($a_while) do
|
32
|
+
loop while @conveyor.output_empty?
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
teardown do
|
@@ -35,33 +39,29 @@ describe 'the Worker' do
|
|
35
39
|
|
36
40
|
given 'valid job data is pushed' do
|
37
41
|
setup do
|
38
|
-
@
|
39
|
-
|
40
|
-
loop until File.exist? worker_output
|
41
|
-
loop while @conveyor.output_empty?
|
42
|
-
end
|
43
|
-
@worker_data = eval File.read(@conveyor.output_file)
|
42
|
+
@logger_data = File.read @workspace_file
|
43
|
+
@conveyor_data = eval File.read(@conveyor.output_file)
|
44
44
|
end
|
45
45
|
|
46
46
|
should 'run the commands' do
|
47
|
-
|
47
|
+
assert_not_equal '', @logger_data
|
48
48
|
end
|
49
49
|
|
50
50
|
should 'run with the context as environment variables' do
|
51
|
-
assert_match /hello world/,
|
51
|
+
assert_match /hello world/, @logger_data
|
52
52
|
end
|
53
53
|
|
54
54
|
should 'run with custom scripts in the path' do
|
55
|
-
assert_match /custom/,
|
55
|
+
assert_match /custom/, @logger_data
|
56
56
|
end
|
57
57
|
|
58
58
|
should 'run implicit jobs' do
|
59
|
-
assert_match /implicit/,
|
59
|
+
assert_match /implicit/, @logger_data
|
60
60
|
end
|
61
61
|
|
62
62
|
should 'tell the conveyor that job is complete' do
|
63
|
-
assert_equal 'finish', @
|
64
|
-
assert_kind_of Fixnum, @
|
63
|
+
assert_equal 'finish', @conveyor_data[:method]
|
64
|
+
assert_kind_of Fixnum, @conveyor_data[:data]
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: robot_sweatshop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Scott
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faker
|
@@ -270,6 +270,7 @@ executables:
|
|
270
270
|
- sweatshop-assembler
|
271
271
|
- sweatshop-conveyor
|
272
272
|
- sweatshop-job-dictionary
|
273
|
+
- sweatshop-logger
|
273
274
|
- sweatshop-overseer
|
274
275
|
- sweatshop-payload-parser
|
275
276
|
- sweatshop-worker
|
@@ -289,6 +290,7 @@ files:
|
|
289
290
|
- bin/sweatshop-assembler
|
290
291
|
- bin/sweatshop-conveyor
|
291
292
|
- bin/sweatshop-job-dictionary
|
293
|
+
- bin/sweatshop-logger
|
292
294
|
- bin/sweatshop-overseer
|
293
295
|
- bin/sweatshop-payload-parser
|
294
296
|
- bin/sweatshop-worker
|
@@ -331,6 +333,7 @@ files:
|
|
331
333
|
- test/data/weird_job.yaml
|
332
334
|
- test/end-to-end_spec.rb
|
333
335
|
- test/job_dictionary_spec.rb
|
336
|
+
- test/logger_spec.rb
|
334
337
|
- test/overseer_spec.rb
|
335
338
|
- test/payload_parser_spec.rb
|
336
339
|
- test/shared/helpers.rb
|