vx-worker 0.2.0.pre28
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 +7 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +276 -0
- data/Rakefile +27 -0
- data/bin/vx-worker +6 -0
- data/docker/Dockerfile +15 -0
- data/docker/bootstrap.sh +106 -0
- data/docker/sv-enable +26 -0
- data/docker/sv-gen +50 -0
- data/lib/vx/worker/cli.rb +55 -0
- data/lib/vx/worker/configuration.rb +62 -0
- data/lib/vx/worker/consumers/job_logs_consumer.rb +13 -0
- data/lib/vx/worker/consumers/job_status_consumer.rb +13 -0
- data/lib/vx/worker/consumers/jobs_consumer.rb +28 -0
- data/lib/vx/worker/docker.rb +32 -0
- data/lib/vx/worker/ext/string.rb +10 -0
- data/lib/vx/worker/helper/config.rb +11 -0
- data/lib/vx/worker/helper/logger.rb +11 -0
- data/lib/vx/worker/initializers/amqp.rb +3 -0
- data/lib/vx/worker/job.rb +49 -0
- data/lib/vx/worker/local.rb +32 -0
- data/lib/vx/worker/middlewares/log_job.rb +19 -0
- data/lib/vx/worker/middlewares/run_script.rb +84 -0
- data/lib/vx/worker/middlewares/start_connector.rb +32 -0
- data/lib/vx/worker/middlewares/timeout.rb +22 -0
- data/lib/vx/worker/middlewares/update_job_status.rb +69 -0
- data/lib/vx/worker/version.rb +5 -0
- data/lib/vx/worker.rb +83 -0
- data/spec/lib/worker/configuration_spec.rb +40 -0
- data/spec/lib/worker/docker_spec.rb +28 -0
- data/spec/lib/worker/job_spec.rb +104 -0
- data/spec/lib/worker/local_spec.rb +29 -0
- data/spec/lib/worker/middlewares/log_job_spec.rb +15 -0
- data/spec/lib/worker/middlewares/run_script_spec.rb +63 -0
- data/spec/lib/worker/middlewares/start_connector_spec.rb +34 -0
- data/spec/lib/worker/middlewares/timeout_spec.rb +28 -0
- data/spec/lib/worker/middlewares/update_job_status_spec.rb +75 -0
- data/spec/lib/worker_spec.rb +39 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/all_job_log_output.rb +3 -0
- data/spec/support/create.rb +19 -0
- data/spec/support/last_job_logs_message.rb +3 -0
- data/spec/support/shared_examples/update_job_status_message_spec.rb +6 -0
- data/vx-worker.gemspec +31 -0
- metadata +231 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::Job do
|
4
|
+
let(:message) { create :message, 'PerformJob' }
|
5
|
+
let(:job) { described_class.new message }
|
6
|
+
|
7
|
+
subject { job }
|
8
|
+
|
9
|
+
context "just created" do
|
10
|
+
its(:message) { should eq message }
|
11
|
+
its(:output) { should be_an_instance_of(Vx::Common::OutputBuffer) }
|
12
|
+
its(:output_counter) { should eq 0 }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "publish_job_log_message" do
|
16
|
+
let(:data) { 'log' }
|
17
|
+
subject { job.publish_job_log_message data }
|
18
|
+
|
19
|
+
it { should be_an_instance_of(Vx::Message::JobLog) }
|
20
|
+
its(:job_id) { should eq job.message.job_id }
|
21
|
+
its(:build_id) { should eq job.message.id }
|
22
|
+
its(:tm) { should eq 1 }
|
23
|
+
its(:log) { should eq data }
|
24
|
+
|
25
|
+
it "should increment counter" do
|
26
|
+
expect {
|
27
|
+
subject
|
28
|
+
}.to change(job, :output_counter).by(1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "add_to_output" do
|
33
|
+
let(:data) { 'data' }
|
34
|
+
let(:messages) { Vx::Worker::JobLogsConsumer.messages }
|
35
|
+
subject do
|
36
|
+
job.add_to_output(data)
|
37
|
+
job.output.flush
|
38
|
+
job
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should delivery message" do
|
42
|
+
expect {
|
43
|
+
subject
|
44
|
+
}.to change(messages, :size).by(1)
|
45
|
+
expect(messages.first.log).to eq data
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should increment output_counter" do
|
49
|
+
expect {
|
50
|
+
subject
|
51
|
+
}.to change(job, :output_counter).by(1)
|
52
|
+
expect(messages.first.tm).to eq 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "add_command_to_output" do
|
57
|
+
let(:data) { 'data' }
|
58
|
+
let(:messages) { Vx::Worker::JobLogsConsumer.messages }
|
59
|
+
subject do
|
60
|
+
job.add_command_to_output(data)
|
61
|
+
job.output.flush
|
62
|
+
job
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should delivery message" do
|
66
|
+
expect {
|
67
|
+
subject
|
68
|
+
}.to change(messages, :size).by(1)
|
69
|
+
expect(messages.first.log).to eq "$ #{data}\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should increment output_counter" do
|
73
|
+
expect {
|
74
|
+
subject
|
75
|
+
}.to change(job, :output_counter).by(1)
|
76
|
+
expect(messages.first.tm).to eq 1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "add_trace_to_output" do
|
81
|
+
let(:data) { 'data' }
|
82
|
+
let(:messages) { Vx::Worker::JobLogsConsumer.messages }
|
83
|
+
subject do
|
84
|
+
job.add_trace_to_output(data)
|
85
|
+
job.output.flush
|
86
|
+
job
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should delivery message" do
|
90
|
+
expect {
|
91
|
+
subject
|
92
|
+
}.to change(messages, :size).by(1)
|
93
|
+
expect(messages.first.log).to eq " ===> #{data}\n"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should increment output_counter" do
|
97
|
+
expect {
|
98
|
+
subject
|
99
|
+
}.to change(job, :output_counter).by(1)
|
100
|
+
expect(messages.first.tm).to eq 1
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::Local do
|
4
|
+
let(:options) { { } }
|
5
|
+
let(:job) { create :job, options }
|
6
|
+
let(:local) { described_class.new job, nil }
|
7
|
+
subject { local }
|
8
|
+
|
9
|
+
context "perform" do
|
10
|
+
subject { local.perform }
|
11
|
+
|
12
|
+
before do
|
13
|
+
Vx::Worker.config.run = "local"
|
14
|
+
end
|
15
|
+
|
16
|
+
it { should eq 0 }
|
17
|
+
|
18
|
+
context "when fail before_script" do
|
19
|
+
let(:options) { { before_script: "/bin/false" } }
|
20
|
+
it { should eq(-1) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when fail script" do
|
24
|
+
let(:options) { { script: "/bin/false" } }
|
25
|
+
it { should satisfy { |n| [1,127].include?(n) } }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::LogJob do
|
4
|
+
let(:exit_code) { 0 }
|
5
|
+
let(:app) { ->(_) { exit_code } }
|
6
|
+
let(:job) { create :job }
|
7
|
+
let(:env) { OpenStruct.new job: job }
|
8
|
+
let(:mid) { described_class.new app }
|
9
|
+
|
10
|
+
subject { mid.call env }
|
11
|
+
|
12
|
+
it { should eq 0 }
|
13
|
+
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::RunScript do
|
4
|
+
let(:exit_code) { 0 }
|
5
|
+
let(:app) { ->(_) { exit_code } }
|
6
|
+
let(:script) { "echo script" }
|
7
|
+
let(:before_script) { "echo before_script" }
|
8
|
+
let(:after_script) { "echo after_script" }
|
9
|
+
let(:job) { create :job,
|
10
|
+
script: script,
|
11
|
+
before_script: before_script,
|
12
|
+
after_script: after_script }
|
13
|
+
let(:env) { OpenStruct.new job: job }
|
14
|
+
let(:mid) { described_class.new app }
|
15
|
+
let(:connector_mid) { Vx::Worker::StartConnector.new(mid) }
|
16
|
+
|
17
|
+
subject { connector_mid.call env }
|
18
|
+
|
19
|
+
shared_examples "run script" do
|
20
|
+
|
21
|
+
it "should be" do
|
22
|
+
expect(subject).to eq 0
|
23
|
+
job.release
|
24
|
+
expect(all_job_log_output).to match("script")
|
25
|
+
expect(all_job_log_output).to match("after_script")
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when script failed" do
|
29
|
+
let(:script) { "false" }
|
30
|
+
it "should be" do
|
31
|
+
expect(subject).to eq(1)
|
32
|
+
job.release
|
33
|
+
expect(all_job_log_output).to match("after_script")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when before_script failed" do
|
38
|
+
let(:before_script) { "false" }
|
39
|
+
it "should be" do
|
40
|
+
expect(subject).to eq(-1)
|
41
|
+
job.release
|
42
|
+
expect(all_job_log_output).to match("after_script")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "local connector" do
|
48
|
+
before do
|
49
|
+
Vx::Worker.config.run = "local"
|
50
|
+
end
|
51
|
+
|
52
|
+
it_should_behave_like "run script"
|
53
|
+
end
|
54
|
+
|
55
|
+
context "local connector", docker: true do
|
56
|
+
before do
|
57
|
+
Vx::Worker.config.run = "docker"
|
58
|
+
end
|
59
|
+
|
60
|
+
it_should_behave_like "run script"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::StartConnector do
|
4
|
+
let(:exit_code) { 0 }
|
5
|
+
let(:app) { ->(_) { exit_code } }
|
6
|
+
let(:job) { create :job }
|
7
|
+
let(:env) { OpenStruct.new job: job }
|
8
|
+
let(:mid) { described_class.new app }
|
9
|
+
|
10
|
+
subject { mid.call env }
|
11
|
+
|
12
|
+
context "local connector" do
|
13
|
+
before do
|
14
|
+
Vx::Worker.config.run = "local"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should successfully start" do
|
18
|
+
expect(subject).to eq 0
|
19
|
+
expect(env.connector).to be
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "docker connector", docker: true do
|
24
|
+
before do
|
25
|
+
Vx::Worker.config.run = "docker"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should successfully start" do
|
29
|
+
expect(subject).to eq 0
|
30
|
+
expect(env.connector).to be
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::Timeout do
|
4
|
+
let(:exit_code) { 0 }
|
5
|
+
let(:app) { ->(_) { exit_code } }
|
6
|
+
let(:env) { OpenStruct.new }
|
7
|
+
let(:mid) { described_class.new app }
|
8
|
+
|
9
|
+
subject { mid.call env }
|
10
|
+
|
11
|
+
it { should eq 0 }
|
12
|
+
|
13
|
+
context "when timeout happened" do
|
14
|
+
let(:app) { ->(_) { sleep 1 ; exit_code } }
|
15
|
+
|
16
|
+
before do
|
17
|
+
mock(mid)._timeout { 0.1 }
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should raise" do
|
21
|
+
expect {
|
22
|
+
subject
|
23
|
+
}.to raise_error(Timeout::Error)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker::UpdateJobStatus do
|
4
|
+
let(:exit_code) { 0 }
|
5
|
+
let(:app) { ->(_) { exit_code } }
|
6
|
+
let(:job) { create :job }
|
7
|
+
let(:env) { OpenStruct.new job: job }
|
8
|
+
let(:mid) { described_class.new app }
|
9
|
+
let(:messages) { Vx::Worker::JobStatusConsumer.messages }
|
10
|
+
|
11
|
+
subject { mid.call env }
|
12
|
+
|
13
|
+
it "should delivery 2 messages" do
|
14
|
+
expect {
|
15
|
+
subject
|
16
|
+
}.to change(messages, :size).by(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
{ 0 => 3, 1 => 4, -1 => 5 }.each do |code, status|
|
20
|
+
context "when exit code is #{code}" do
|
21
|
+
let(:exit_code) { code }
|
22
|
+
it { should eq code }
|
23
|
+
|
24
|
+
context "messages" do
|
25
|
+
before { mid.call env }
|
26
|
+
|
27
|
+
context "first" do
|
28
|
+
subject { messages.first }
|
29
|
+
it_should_behave_like "UpdateJobStatus message" do
|
30
|
+
its(:status) { should eq 2 }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "last" do
|
35
|
+
subject { messages.last }
|
36
|
+
it_should_behave_like "UpdateJobStatus message" do
|
37
|
+
its(:status) { should eq status }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when raise exception" do
|
46
|
+
let(:app) { ->(_) { raise "Ignore Me" } }
|
47
|
+
it { should eq(-1) }
|
48
|
+
|
49
|
+
context "messages" do
|
50
|
+
before { mid.call env }
|
51
|
+
|
52
|
+
context "first" do
|
53
|
+
subject { messages.first }
|
54
|
+
it_should_behave_like "UpdateJobStatus message" do
|
55
|
+
its(:status) { should eq 2 }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "last" do
|
60
|
+
subject { messages.last }
|
61
|
+
it_should_behave_like "UpdateJobStatus message" do
|
62
|
+
its(:status) { should eq 5 }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "Timeout::Error" do
|
68
|
+
let(:app) { ->(_) { raise Timeout::Error.new("Timeout Ignore Me") } }
|
69
|
+
|
70
|
+
it { should eq(-1) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vx::Worker do
|
4
|
+
|
5
|
+
context ".perform" do
|
6
|
+
let(:job) { create :job }
|
7
|
+
let(:run) { :docker }
|
8
|
+
subject { described_class.perform job, '/tmp' }
|
9
|
+
|
10
|
+
before do
|
11
|
+
described_class.configure do |c|
|
12
|
+
c.run = run
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when run at :docker" do
|
17
|
+
let(:run) { :docker }
|
18
|
+
let(:docker) { 'docker' }
|
19
|
+
before do
|
20
|
+
mock(Vx::Worker::Docker).new(job, '/tmp') { docker }
|
21
|
+
mock(docker).perform { true }
|
22
|
+
end
|
23
|
+
|
24
|
+
it { should be }
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when run at :local" do
|
28
|
+
let(:run) { :local }
|
29
|
+
let(:local) { 'local' }
|
30
|
+
before do
|
31
|
+
mock(Vx::Worker::Local).new(job, '/tmp') { local }
|
32
|
+
mock(local).perform { true }
|
33
|
+
end
|
34
|
+
|
35
|
+
it { should be }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path '../../lib/vx/worker', __FILE__
|
2
|
+
|
3
|
+
Bundler.require(:test)
|
4
|
+
require 'rspec/autorun'
|
5
|
+
require 'vx/common/amqp/testing'
|
6
|
+
require 'vx/message/testing'
|
7
|
+
|
8
|
+
Dir[File.expand_path("../..", __FILE__) + "/spec/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.mock_with :rr
|
12
|
+
|
13
|
+
config.before(:each) do
|
14
|
+
Vx::Common::AMQP::Testing.clear
|
15
|
+
Vx::Worker.reset_config!
|
16
|
+
|
17
|
+
Vx::Worker.configure do |c|
|
18
|
+
=begin
|
19
|
+
c.docker.ssh.port = 2223
|
20
|
+
c.docker.ssh.host = 'localhost'
|
21
|
+
c.docker.create_options = {
|
22
|
+
'PortSpecs' => ['2022:22']
|
23
|
+
}
|
24
|
+
=end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
def create(who, *args)
|
4
|
+
|
5
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
6
|
+
|
7
|
+
case who
|
8
|
+
|
9
|
+
when :message
|
10
|
+
name = args.shift
|
11
|
+
klass = Vx::Message.const_get name
|
12
|
+
klass.test_message options
|
13
|
+
|
14
|
+
when :job
|
15
|
+
message = options[:message] || create(:message, 'PerformJob', options)
|
16
|
+
Vx::Worker::Job.new message
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/vx-worker.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require File.expand_path('../lib/vx/worker/version.rb', __FILE__)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "vx-worker"
|
8
|
+
spec.version = Vx::Worker::VERSION
|
9
|
+
spec.authors = ["Dmitry Galinsky"]
|
10
|
+
spec.email = ["dima.exe@gmail.com"]
|
11
|
+
spec.description = %q{ ci worker }
|
12
|
+
spec.summary = %q{ ci worker }
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'vx-common', "= #{Vx::Worker::VERSION}"
|
22
|
+
spec.add_runtime_dependency 'vx-message', "= #{Vx::Worker::VERSION}"
|
23
|
+
spec.add_runtime_dependency 'vx-container_connector', "= #{Vx::Worker::VERSION}"
|
24
|
+
spec.add_runtime_dependency 'vx-common-amqp', '~> 0.2.5'
|
25
|
+
spec.add_runtime_dependency 'hashr', '= 0.0.22'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "rspec"
|
30
|
+
spec.add_development_dependency "rr"
|
31
|
+
end
|