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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE.txt +276 -0
  6. data/Rakefile +27 -0
  7. data/bin/vx-worker +6 -0
  8. data/docker/Dockerfile +15 -0
  9. data/docker/bootstrap.sh +106 -0
  10. data/docker/sv-enable +26 -0
  11. data/docker/sv-gen +50 -0
  12. data/lib/vx/worker/cli.rb +55 -0
  13. data/lib/vx/worker/configuration.rb +62 -0
  14. data/lib/vx/worker/consumers/job_logs_consumer.rb +13 -0
  15. data/lib/vx/worker/consumers/job_status_consumer.rb +13 -0
  16. data/lib/vx/worker/consumers/jobs_consumer.rb +28 -0
  17. data/lib/vx/worker/docker.rb +32 -0
  18. data/lib/vx/worker/ext/string.rb +10 -0
  19. data/lib/vx/worker/helper/config.rb +11 -0
  20. data/lib/vx/worker/helper/logger.rb +11 -0
  21. data/lib/vx/worker/initializers/amqp.rb +3 -0
  22. data/lib/vx/worker/job.rb +49 -0
  23. data/lib/vx/worker/local.rb +32 -0
  24. data/lib/vx/worker/middlewares/log_job.rb +19 -0
  25. data/lib/vx/worker/middlewares/run_script.rb +84 -0
  26. data/lib/vx/worker/middlewares/start_connector.rb +32 -0
  27. data/lib/vx/worker/middlewares/timeout.rb +22 -0
  28. data/lib/vx/worker/middlewares/update_job_status.rb +69 -0
  29. data/lib/vx/worker/version.rb +5 -0
  30. data/lib/vx/worker.rb +83 -0
  31. data/spec/lib/worker/configuration_spec.rb +40 -0
  32. data/spec/lib/worker/docker_spec.rb +28 -0
  33. data/spec/lib/worker/job_spec.rb +104 -0
  34. data/spec/lib/worker/local_spec.rb +29 -0
  35. data/spec/lib/worker/middlewares/log_job_spec.rb +15 -0
  36. data/spec/lib/worker/middlewares/run_script_spec.rb +63 -0
  37. data/spec/lib/worker/middlewares/start_connector_spec.rb +34 -0
  38. data/spec/lib/worker/middlewares/timeout_spec.rb +28 -0
  39. data/spec/lib/worker/middlewares/update_job_status_spec.rb +75 -0
  40. data/spec/lib/worker_spec.rb +39 -0
  41. data/spec/spec_helper.rb +27 -0
  42. data/spec/support/all_job_log_output.rb +3 -0
  43. data/spec/support/create.rb +19 -0
  44. data/spec/support/last_job_logs_message.rb +3 -0
  45. data/spec/support/shared_examples/update_job_status_message_spec.rb +6 -0
  46. data/vx-worker.gemspec +31 -0
  47. 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
@@ -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,3 @@
1
+ def last_job_log_message
2
+ Vx::Worker::JobLogsConsumer.messages.last
3
+ 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
@@ -0,0 +1,3 @@
1
+ def all_job_log_output
2
+ Vx::Worker::JobLogsConsumer.messages.map{|i| i.log }.join("\n")
3
+ end
@@ -0,0 +1,6 @@
1
+ shared_examples "UpdateJobStatus message" do
2
+ its(:build_id) { should eq job.message.id }
3
+ its(:job_id) { should eq job.message.job_id }
4
+ its(:matrix) { should eq job.message.matrix_keys }
5
+ its(:tm) { should be }
6
+ 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