evrone-ci-router 0.2.0.pre0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/Gemfile +7 -0
- data/README.md +1 -0
- data/Rakefile +22 -0
- data/bin/cli +3 -0
- data/bin/git_ssh +3 -0
- data/bin/jobs_publisher +12 -0
- data/bin/workers +13 -0
- data/evrone-ci-router.gemspec +30 -0
- data/fixtures/travis.yml +5 -0
- data/lib/evrone/ci/router.rb +100 -0
- data/lib/evrone/ci/router/build.rb +60 -0
- data/lib/evrone/ci/router/build_matrix.rb +89 -0
- data/lib/evrone/ci/router/configuration.rb +27 -0
- data/lib/evrone/ci/router/consumers/build_logs_consumer.rb +15 -0
- data/lib/evrone/ci/router/consumers/build_status_consumer.rb +15 -0
- data/lib/evrone/ci/router/consumers/builds_consumer.rb +28 -0
- data/lib/evrone/ci/router/consumers/jobs_consumer.rb +15 -0
- data/lib/evrone/ci/router/ext/array.rb +5 -0
- data/lib/evrone/ci/router/ext/string.rb +9 -0
- data/lib/evrone/ci/router/helper/config.rb +13 -0
- data/lib/evrone/ci/router/helper/logger.rb +13 -0
- data/lib/evrone/ci/router/helper/trace_sh_command.rb +14 -0
- data/lib/evrone/ci/router/initializers/amqp.rb +63 -0
- data/lib/evrone/ci/router/middleware/create_build_matrix.rb +54 -0
- data/lib/evrone/ci/router/middleware/create_dirs.rb +25 -0
- data/lib/evrone/ci/router/middleware/fetch_commit_info.rb +22 -0
- data/lib/evrone/ci/router/middleware/fetch_source.rb +36 -0
- data/lib/evrone/ci/router/middleware/log_build.rb +24 -0
- data/lib/evrone/ci/router/middleware/travis/env.rb +21 -0
- data/lib/evrone/ci/router/middleware/travis/ruby.rb +55 -0
- data/lib/evrone/ci/router/middleware/travis/script.rb +25 -0
- data/lib/evrone/ci/router/middleware/update_build_status.rb +75 -0
- data/lib/evrone/ci/router/queue.rb +58 -0
- data/lib/evrone/ci/router/travis.rb +104 -0
- data/lib/evrone/ci/router/travis/serializable.rb +45 -0
- data/lib/evrone/ci/router/version.rb +7 -0
- data/spec/lib/build_matrix_spec.rb +145 -0
- data/spec/lib/build_spec.rb +75 -0
- data/spec/lib/configuration_spec.rb +22 -0
- data/spec/lib/middleware/create_build_matrix_spec.rb +73 -0
- data/spec/lib/middleware/create_dirs_spec.rb +26 -0
- data/spec/lib/middleware/fetch_commit_info_spec.rb +23 -0
- data/spec/lib/middleware/fetch_source_spec.rb +27 -0
- data/spec/lib/middleware/log_build_spec.rb +14 -0
- data/spec/lib/middleware/update_build_status_spec.rb +70 -0
- data/spec/lib/queue_spec.rb +55 -0
- data/spec/lib/travis_spec.rb +182 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/create.rb +47 -0
- data/spec/support/fixture.rb +7 -0
- data/spec/support/shared_examples/update_build_status_message.rb +5 -0
- metadata +228 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Router::Configuration do
|
4
|
+
let(:config) { Evrone::CI::Router.config }
|
5
|
+
subject { config }
|
6
|
+
|
7
|
+
before { Evrone::CI::Router.reset_config! }
|
8
|
+
|
9
|
+
its(:timeout) { should eq 1800 }
|
10
|
+
its(:amqp_url) { should be_nil }
|
11
|
+
|
12
|
+
context ".configure" do
|
13
|
+
subject {
|
14
|
+
Evrone::CI::Router.configure do |c|
|
15
|
+
c.timeout = 1
|
16
|
+
c.amqp_url = "2"
|
17
|
+
end
|
18
|
+
}
|
19
|
+
its(:timeout) { should eq 1 }
|
20
|
+
its(:amqp_url) { should eq "2" }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
describe Evrone::CI::Router::Middleware::CreateBuildMatrix do
|
5
|
+
let(:app) { ->(_) { 0 } }
|
6
|
+
let(:build) { create :build }
|
7
|
+
let(:env) { OpenStruct.new build: build, repo_dir: repo_dir }
|
8
|
+
let(:repo_dir) { Pathname.new fixture_path("repo") }
|
9
|
+
let(:matrix) { described_class.new app }
|
10
|
+
|
11
|
+
it { should be }
|
12
|
+
|
13
|
+
context "call" do
|
14
|
+
let(:travis) { create :travis, attributes: { rvm: %w{ 1.9.3 2.0.0 } } }
|
15
|
+
subject { matrix.call env }
|
16
|
+
|
17
|
+
context "successfuly" do
|
18
|
+
before do
|
19
|
+
mock(matrix).load_travis(repo_dir) { travis }
|
20
|
+
end
|
21
|
+
|
22
|
+
it { should eq 0 }
|
23
|
+
|
24
|
+
it "should create and delivery jobs " do
|
25
|
+
expect{ subject }.to change{
|
26
|
+
Evrone::CI::Router::JobsConsumer.messages.count
|
27
|
+
}.by(2)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "first delivered job" do
|
31
|
+
let(:m) { Evrone::CI::Router::JobsConsumer.messages.first }
|
32
|
+
subject { m }
|
33
|
+
before { matrix.call env }
|
34
|
+
|
35
|
+
its("job_id") { should eq 1 }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "last delivered job" do
|
39
|
+
let(:m) { Evrone::CI::Router::JobsConsumer.messages.last }
|
40
|
+
subject { m }
|
41
|
+
before { matrix.call env }
|
42
|
+
|
43
|
+
its("job_id") { should eq 2 }
|
44
|
+
end
|
45
|
+
|
46
|
+
context "update build" do
|
47
|
+
it "should assign jobs_count" do
|
48
|
+
expect{ subject }.to change(build, :jobs_count).from(nil).to(2)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should assign matrix" do
|
52
|
+
expect{ subject }.to change(build, :matrix).from(nil).to(%w{rvm})
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when travis.yml not found" do
|
58
|
+
|
59
|
+
before do
|
60
|
+
mock(Evrone::CI::Router::Travis).from_file(anything){ nil }
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return -1" do
|
64
|
+
expect(subject).to eq(-1)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "cannot delivery any job" do
|
68
|
+
expect{ subject }.to_not change(Evrone::CI::Router::JobsConsumer.messages, :size)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pathname'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe Evrone::CI::Router::Middleware::CreateDirs do
|
6
|
+
let(:build) { create :build }
|
7
|
+
let(:path_prefix) { Pathname.new '/tmp/.test' }
|
8
|
+
let(:app) { ->(_) { 0 } }
|
9
|
+
let(:env) { OpenStruct.new build: build, path_prefix: path_prefix }
|
10
|
+
|
11
|
+
subject { described_class.new app }
|
12
|
+
|
13
|
+
before { FileUtils.rm_rf path_prefix }
|
14
|
+
after { FileUtils.rm_rf path_prefix }
|
15
|
+
|
16
|
+
context "call" do
|
17
|
+
subject{ described_class.new(app).call env }
|
18
|
+
it { should eq 0 }
|
19
|
+
|
20
|
+
it "should create and assign to env repo_dir" do
|
21
|
+
subject
|
22
|
+
expect(env.repo_dir.to_s).to eq '/tmp/.test/repo'
|
23
|
+
expect(File.directory? env.repo_dir).to be
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Router::Middleware::FetchCommitInfo do
|
4
|
+
let(:build) { create :build }
|
5
|
+
let(:env) { OpenStruct.new build: build, scm: scm }
|
6
|
+
let(:app) { ->(_) { 0 } }
|
7
|
+
let(:commit_info) { 'commit_info' }
|
8
|
+
let(:scm) { 'scm' }
|
9
|
+
subject { described_class.new(app).call env }
|
10
|
+
|
11
|
+
before do
|
12
|
+
mock(scm).commit_info { commit_info }
|
13
|
+
end
|
14
|
+
|
15
|
+
it { should eq 0 }
|
16
|
+
|
17
|
+
it "should assign commit info to build" do
|
18
|
+
subject
|
19
|
+
expect(build.commit_info).to eq commit_info
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pathname'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe Evrone::CI::Router::Middleware::FetchSource do
|
6
|
+
let(:path_prefix) { '/tmp/.test' }
|
7
|
+
let(:build) { create :build, options }
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:repo_dir) { Pathname.new '/tmp/.test' }
|
10
|
+
let(:app) { ->(_) { 0 } }
|
11
|
+
let(:env) { OpenStruct.new build: build, repo_dir: repo_dir }
|
12
|
+
subject { described_class.new(app).call env }
|
13
|
+
|
14
|
+
before { FileUtils.rm_rf(repo_dir) }
|
15
|
+
after { FileUtils.rm_rf(repo_dir) }
|
16
|
+
|
17
|
+
it "should checkout repo" do
|
18
|
+
expect(subject).to eq 0
|
19
|
+
expect(File.directory? "/tmp/.test/.git").to be
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when failed" do
|
23
|
+
let(:options) { { src: "/not-exists.git" } }
|
24
|
+
it { should eq(-1) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Router::Middleware::LogBuild do
|
4
|
+
let(:build) { create :build }
|
5
|
+
let(:app) { ->(_) { 0 } }
|
6
|
+
let(:env) { OpenStruct.new build: build }
|
7
|
+
|
8
|
+
subject { described_class.new app }
|
9
|
+
|
10
|
+
context "call" do
|
11
|
+
subject{ described_class.new(app).call env }
|
12
|
+
it { should eq 0 }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Router::Middleware::UpdateBuildStatus do
|
4
|
+
let(:exit_code) { 0 }
|
5
|
+
let(:app) { ->(_) { exit_code } }
|
6
|
+
let(:build) { create :build }
|
7
|
+
let(:env) { OpenStruct.new build: build }
|
8
|
+
let(:mid) { described_class.new app }
|
9
|
+
let(:messages) { Evrone::CI::Router::BuildStatusConsumer.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 "UpdateBuildStatus 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 "UpdateBuildStatus 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 "UpdateBuildStatus 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 "UpdateBuildStatus message" do
|
62
|
+
its(:status) { should eq 5 }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Router::Queue do
|
4
|
+
let(:travis) { create :travis }
|
5
|
+
let(:queue) { described_class.new travis }
|
6
|
+
let(:expected_before_script) {
|
7
|
+
s = ["set -e"]
|
8
|
+
s << "export LC_ALL=en_US.UTF8"
|
9
|
+
s << "eval \"$(rbenv init -)\" || true"
|
10
|
+
s << %{
|
11
|
+
rbenv shell
|
12
|
+
$(rbenv versions |
|
13
|
+
sed -e 's/^*/ /' |
|
14
|
+
awk '{print $1}' |
|
15
|
+
grep -v 'system' |
|
16
|
+
grep '2.0.0' |
|
17
|
+
tail -n1)
|
18
|
+
}.compact
|
19
|
+
s << 'export BUNDLE_GEMFILE=${PWD}/Gemfile'
|
20
|
+
s << "export GEM_HOME=/tmp/.rubygems"
|
21
|
+
trace s, "env"
|
22
|
+
s << "gem query -q -in '^bundler$' > /dev/null || gem install bundler -q --no-rdoc --no-ri"
|
23
|
+
trace s, "ruby --version"
|
24
|
+
trace s, "gem --version"
|
25
|
+
trace s, "bundle --version"
|
26
|
+
trace s, "bundle install"
|
27
|
+
trace s, "echo before_script"
|
28
|
+
s.join("\n")
|
29
|
+
}
|
30
|
+
let(:expected_script) {
|
31
|
+
s = ["set -e"]
|
32
|
+
trace s, "RAILS_ENV=test ls -1 && echo DONE!"
|
33
|
+
s.join("\n")
|
34
|
+
}
|
35
|
+
subject { queue }
|
36
|
+
|
37
|
+
its(:travis) { should eq travis }
|
38
|
+
|
39
|
+
context "to_before_script" do
|
40
|
+
subject { queue.to_before_script }
|
41
|
+
|
42
|
+
it { should eq expected_before_script }
|
43
|
+
end
|
44
|
+
|
45
|
+
context "to_script" do
|
46
|
+
subject { queue.to_script }
|
47
|
+
|
48
|
+
it { should eq expected_script }
|
49
|
+
end
|
50
|
+
|
51
|
+
def trace(s, cmd)
|
52
|
+
s << "echo #{Shellwords.escape "$ " + cmd}"
|
53
|
+
s << cmd
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Router::Travis do
|
4
|
+
let(:content) { YAML.load fixture('travis.yml') }
|
5
|
+
let(:travis) { described_class.from_attributes content }
|
6
|
+
subject { travis }
|
7
|
+
|
8
|
+
its(:attributes) { should be }
|
9
|
+
its(:rvm) { should eq %w{ 2.0.0 } }
|
10
|
+
its(:before_script) { should eq ["echo before_script"] }
|
11
|
+
its(:script) { should eq ["RAILS_ENV=test ls -1 && echo DONE!"] }
|
12
|
+
|
13
|
+
context "merge" do
|
14
|
+
let(:new_attrs) { { rvm: "replaced" } }
|
15
|
+
subject{ travis.merge new_attrs }
|
16
|
+
|
17
|
+
it "should build a new travis instance" do
|
18
|
+
expect(subject).to be_an_instance_of(described_class)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should replace attributes" do
|
22
|
+
expect(subject.attributes["rvm"]).to eq %w{ replaced }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "(serialization)" do
|
27
|
+
|
28
|
+
context "build new instance" do
|
29
|
+
let(:expected) { {
|
30
|
+
"rvm" => ["2.0.0"],
|
31
|
+
"before_script" => ["echo before_script"],
|
32
|
+
"script" => ["RAILS_ENV=test ls -1 && echo DONE!"],
|
33
|
+
"env" => {
|
34
|
+
"matrix" => [],
|
35
|
+
"global" => []
|
36
|
+
}
|
37
|
+
} }
|
38
|
+
|
39
|
+
context "from_yaml" do
|
40
|
+
subject { described_class.from_yaml(fixture('travis.yml')).attributes }
|
41
|
+
it { should eq expected }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "form_file" do
|
45
|
+
subject { described_class.from_file('fixtures/travis.yml').attributes }
|
46
|
+
it { should eq expected }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "from_attributes" do
|
50
|
+
let(:attrs) {{
|
51
|
+
rvm: "2.0.0",
|
52
|
+
before_script: "echo before_script",
|
53
|
+
script: "RAILS_ENV=test ls -1 && echo DONE!"
|
54
|
+
}}
|
55
|
+
subject { described_class.from_attributes(attrs).attributes }
|
56
|
+
it { should eq expected }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context ".to_yaml" do
|
61
|
+
subject { travis.to_yaml }
|
62
|
+
it { should eq travis.attributes.to_yaml }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "to_queue" do
|
67
|
+
subject { travis.to_queue }
|
68
|
+
it { should be }
|
69
|
+
end
|
70
|
+
|
71
|
+
context "to_matrix_s" do
|
72
|
+
subject { travis.to_matrix_s }
|
73
|
+
it { should eq 'rvm:2.0.0' }
|
74
|
+
|
75
|
+
context "when many items" do
|
76
|
+
before do
|
77
|
+
mock(travis).rvm { %w{ 1.9.3 2.0.0 } }
|
78
|
+
mock(travis).scala { %w{ 2.10.1 } }
|
79
|
+
end
|
80
|
+
it { should eq "rvm:1.9.3, rvm:2.0.0, scala:2.10.1" }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "matrix_keys" do
|
85
|
+
subject { travis.matrix_keys }
|
86
|
+
it { should eq %w{ rvm:2.0.0 } }
|
87
|
+
|
88
|
+
context "when many items" do
|
89
|
+
before do
|
90
|
+
mock(travis).rvm { %w{ 1.9.3 2.0.0 } }
|
91
|
+
mock(travis).scala { %w{ 2.10.1 } }
|
92
|
+
end
|
93
|
+
it { should eq %w{ rvm:1.9.3 rvm:2.0.0 scala:2.10.1 }}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
it "empty attributes must be empty Array" do
|
99
|
+
expect(travis.scala).to eq([])
|
100
|
+
end
|
101
|
+
|
102
|
+
context "normalize_attributes" do
|
103
|
+
described_class::AS_ARRAY.each do |m|
|
104
|
+
context "convert #{m} attribute to Array" do
|
105
|
+
let(:content) { { m => m } }
|
106
|
+
subject { travis.__send__(m) }
|
107
|
+
it { should eq([m]) }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "convert hash keys to strings" do
|
112
|
+
let(:content) { { rvm: "rvm" } }
|
113
|
+
subject { travis.attributes }
|
114
|
+
it { should include("rvm" => %w{rvm}) }
|
115
|
+
end
|
116
|
+
|
117
|
+
context "build env hash" do
|
118
|
+
subject { travis.attributes["env"] }
|
119
|
+
|
120
|
+
context "from String" do
|
121
|
+
let(:content) { { env: "FOO" } }
|
122
|
+
it { should eq( "global" => [], "matrix" => %w{ FOO } ) }
|
123
|
+
end
|
124
|
+
|
125
|
+
context "from Array" do
|
126
|
+
let(:content) { { env: %w{ FOO BAR } } }
|
127
|
+
it { should eq( 'global' => [], 'matrix' => %w{ FOO BAR } ) }
|
128
|
+
end
|
129
|
+
|
130
|
+
context "from empty Hash" do
|
131
|
+
let(:content) { { env: {} } }
|
132
|
+
it { should eq( 'global' => [], 'matrix' => [] ) }
|
133
|
+
end
|
134
|
+
|
135
|
+
context "from Hash" do
|
136
|
+
let(:content) { { env: { "global" => "1", 'matrix' => '2' } } }
|
137
|
+
it { should eq( 'global' => %w{1}, 'matrix' => %w{2} ) }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "env" do
|
143
|
+
let(:content) { { env: env } }
|
144
|
+
subject { travis.env }
|
145
|
+
|
146
|
+
context "when attributes[env] is Array" do
|
147
|
+
let(:env) { %w{ FOO=1 BAR=2 } }
|
148
|
+
it { should eq %w{ FOO=1 BAR=2 } }
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when attributes[env] is Hash" do
|
152
|
+
let(:env) { { "matrix" => %w{ BAZ=1 } } }
|
153
|
+
it { should eq %w{ BAZ=1 } }
|
154
|
+
end
|
155
|
+
|
156
|
+
context "when attributes[env] is empty" do
|
157
|
+
let(:env) { {} }
|
158
|
+
it { should eq([]) }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "global_env" do
|
163
|
+
let(:content) { { env: env } }
|
164
|
+
subject { travis.global_env }
|
165
|
+
|
166
|
+
context "when attributes[env] is Array" do
|
167
|
+
let(:env) { %w{ FOO=1 } }
|
168
|
+
it { should eq([]) }
|
169
|
+
end
|
170
|
+
|
171
|
+
context "when attributes[env] is Hash" do
|
172
|
+
let(:env) { { "global" => %w{ FOO=1 } } }
|
173
|
+
it { should eq %w{ FOO=1 } }
|
174
|
+
end
|
175
|
+
|
176
|
+
context "when attributes[env] is empty" do
|
177
|
+
let(:env) { {} }
|
178
|
+
it { should eq([]) }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|