bosh-workspace 0.8.5 → 0.9.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -2
  4. data/.ruby-gemset +1 -1
  5. data/.travis.yml +2 -0
  6. data/Guardfile +2 -2
  7. data/README.md +4 -4
  8. data/bosh-workspace.gemspec +2 -1
  9. data/lib/bosh/cli/commands/deployment_patch.rb +96 -0
  10. data/lib/bosh/cli/commands/prepare.rb +6 -4
  11. data/lib/bosh/workspace/credentials.rb +30 -0
  12. data/lib/bosh/workspace/deployment_patch.rb +90 -0
  13. data/lib/bosh/workspace/helpers/git_credentials_helper.rb +95 -0
  14. data/lib/bosh/workspace/helpers/spiff_helper.rb +1 -0
  15. data/lib/bosh/workspace/project_deployment.rb +2 -44
  16. data/lib/bosh/workspace/release.rb +20 -23
  17. data/lib/bosh/workspace/schemas/credentials.rb +27 -0
  18. data/lib/bosh/workspace/schemas/deployment_patch.rb +15 -0
  19. data/lib/bosh/workspace/schemas/project_deployment.rb +21 -0
  20. data/lib/bosh/workspace/schemas/releases.rb +16 -0
  21. data/lib/bosh/workspace/schemas/stemcells.rb +25 -0
  22. data/lib/bosh/workspace/shell.rb +67 -0
  23. data/lib/bosh/workspace/tasks/bosh_command_runner.rb +29 -0
  24. data/lib/bosh/workspace/tasks/deployment.rb +63 -0
  25. data/lib/bosh/workspace/tasks/workspace.rake +69 -0
  26. data/lib/bosh/workspace/tasks.rb +15 -0
  27. data/lib/bosh/workspace/version.rb +1 -1
  28. data/lib/bosh/workspace.rb +14 -0
  29. data/spec/assets/foo-boshrelease-repo-new-structure.zip +0 -0
  30. data/spec/assets/foo-boshrelease-repo-updated.zip +0 -0
  31. data/spec/assets/foo-boshrelease-repo.zip +0 -0
  32. data/spec/assets/foo-boshworkspace.zip +0 -0
  33. data/spec/commands/deployment_patch_spec.rb +152 -0
  34. data/spec/commands/prepare_spec.rb +5 -3
  35. data/spec/credentials_spec.rb +46 -0
  36. data/spec/deployment_patch_spec.rb +171 -0
  37. data/spec/helpers/git_credentials_helper_spec.rb +160 -0
  38. data/spec/helpers/spiff_helper_spec.rb +16 -3
  39. data/spec/project_deployment_spec.rb +52 -163
  40. data/spec/release_spec.rb +208 -80
  41. data/spec/schemas/credentials_spec.rb +28 -0
  42. data/spec/schemas/deployment_patch_spec.rb +30 -0
  43. data/spec/schemas/project_deployment_spec.rb +45 -0
  44. data/spec/schemas/releases_spec.rb +31 -0
  45. data/spec/schemas/stemcells_spec.rb +37 -0
  46. data/spec/shell_spec.rb +70 -0
  47. data/spec/spec_helper.rb +11 -5
  48. data/spec/support/shared_contexts/rake.rb +37 -0
  49. data/spec/tasks/bosh_command_runner_spec.rb +39 -0
  50. data/spec/tasks/deployment_spec.rb +80 -0
  51. data/spec/tasks/workspace_task_spec.rb +99 -0
  52. metadata +69 -7
data/spec/release_spec.rb CHANGED
@@ -1,123 +1,251 @@
1
1
  describe Bosh::Workspace::Release do
2
- let(:name) { "foo"}
2
+ include Bosh::Workspace::GitCredenialsHelper
3
+ let(:name) { "foo" }
4
+ let(:release) { load_release(release_data) }
3
5
  let(:version) { 3 }
4
- let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
5
6
  let(:release_data) { { "name" => name, "version" => version, "git" => repo } }
6
7
  let(:releases_dir) { File.join(asset_dir("manifests-repo"), ".releases") }
7
- let(:release) { Bosh::Workspace::Release.new release_data, releases_dir }
8
8
  let(:templates) { Dir[File.join(releases_dir, name, "templates/*.yml")].to_s }
9
9
 
10
- describe "#update_repo" do
11
- subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
12
-
13
- context "latest version" do
14
- before { release.update_repo }
10
+ def load_release(release_data)
11
+ Bosh::Workspace::Release.new(release_data, releases_dir).tap do |r|
12
+ fetch_or_clone_repo(r.repo_dir, repo)
13
+ end
14
+ end
15
15
 
16
- let(:version) { "latest" }
16
+ context "given a release with new structure within 'releases' folder" do
17
+ let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-new-structure.zip") }
17
18
 
18
- it "checks out repo" do
19
- expect(subject).to match(/foo-11.yml/)
19
+ describe "#update_repo" do
20
+ subject do
21
+ Dir[File.join(releases_dir, name, "releases/#{name}/foo*.yml")].to_s
20
22
  end
21
23
 
22
- it "does not include templates from master" do
23
- expect(templates).to_not match(/deployment.yml/)
24
+ context "latest version" do
25
+ before { release.update_repo }
26
+
27
+ let(:version) { "latest" }
28
+
29
+ it "checks out repo" do
30
+ expect(subject).to match(/foo-11.yml/)
31
+ end
32
+
33
+ it "does not include templates from master" do
34
+ expect(templates).to_not match(/deployment.yml/)
35
+ end
24
36
  end
25
37
  end
26
38
 
27
- context "specific version" do
28
- let(:version) { "11" }
29
- before { release.update_repo }
39
+ describe "attributes" do
40
+ subject { release }
41
+ its(:name) { should eq name }
42
+ its(:git_url) { should eq repo }
43
+ its(:repo_dir) { should match(/\/#{name}$/) }
44
+ its(:manifest_file) { should match(/\/#{name}-#{version}.yml$/) }
45
+ its(:manifest) { should match "releases/#{name}/#{name}-#{version}.yml$" }
46
+ its(:name_version) { should eq "#{name}/#{version}" }
47
+ its(:version) { should eq version }
48
+ end
49
+ end
50
+
51
+ context "given a release with deprecated structure within 'releases' folder" do
52
+ let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
53
+
54
+ describe "#update_repo" do
55
+ subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
56
+
57
+ context "latest version" do
58
+ before { release.update_repo }
59
+
60
+ let(:version) { "latest" }
61
+
62
+ it "checks out repo" do
63
+ expect(subject).to match(/foo-11.yml/)
64
+ end
30
65
 
31
- it "checks out repo" do
32
- expect(subject).to match(/foo-11.yml/)
66
+ it "does not include templates from master" do
67
+ expect(templates).to_not match(/deployment.yml/)
68
+ end
33
69
  end
34
70
 
35
- it "does not include templates from master" do
36
- expect(templates).to_not match(/deployment.yml/)
71
+ context "specific version" do
72
+ let(:version) { "11" }
73
+ before { release.update_repo }
74
+
75
+ it "checks out repo" do
76
+ expect(subject).to match(/foo-11.yml/)
77
+ end
78
+
79
+ it "does not include templates from master" do
80
+ expect(templates).to_not match(/deployment.yml/)
81
+ end
37
82
  end
38
- end
39
83
 
40
- context "specific version" do
41
- let(:version) { "2" }
84
+ context "specific version" do
85
+ let(:version) { "2" }
42
86
 
43
- it "checks out repo" do
44
- release.update_repo
45
- expect(subject).to match(/foo-2.yml/)
87
+ it "checks out repo" do
88
+ release.update_repo
89
+ expect(subject).to match(/foo-2.yml/)
90
+ end
46
91
  end
47
- end
48
92
 
49
- context "specific ref with latest release" do
50
- let(:release_data) do
51
- { "name" => name, "version" => "latest", "ref" => "66658", "git" => repo }
93
+ context "specific ref with latest release" do
94
+ let(:release_data) do
95
+ {"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
96
+ end
97
+
98
+ it "checks out repo" do
99
+ release.update_repo
100
+ expect(subject).to match(/foo-2.yml/)
101
+ expect(subject).to_not match(/foo-3.yml/)
102
+ end
52
103
  end
53
104
 
54
- it "checks out repo" do
55
- release.update_repo
56
- expect(subject).to match(/foo-2.yml/)
57
- expect(subject).to_not match(/foo-3.yml/)
105
+ context "updated version " do
106
+ let(:version) { "11" }
107
+
108
+ it "checks out file with multiple commits" do
109
+ release.update_repo
110
+ expect(subject).to match(/foo-11.yml/)
111
+ end
58
112
  end
59
- end
60
113
 
61
- context "updated version " do
62
- let(:version) { "11" }
114
+ context "non existing version " do
115
+ let(:version) { "12" }
63
116
 
64
- it "checks out file with multiple commits" do
65
- release.update_repo
66
- expect(subject).to match(/foo-11.yml/)
117
+ it "raises an error" do
118
+ expect { release.update_repo }.
119
+ to raise_error(/Could not find version/)
120
+ end
67
121
  end
68
- end
69
122
 
70
- context "non existing version " do
71
- let(:version) { "12" }
123
+ context "already cloned repo" do
124
+ before do
125
+ load_release("name" => name, "version" => 1, "git" => repo).update_repo
126
+ end
72
127
 
73
- it "raises an error" do
74
- expect { release.update_repo }.
75
- to raise_error(/Could not find version/)
128
+ it "version 3" do
129
+ release.update_repo
130
+ expect(subject).to match(/foo-3.yml/)
131
+ end
76
132
  end
77
- end
78
133
 
79
- context "already cloned repo" do
80
- before do
81
- data = { "name" => name, "version" => 1, "git" => repo }
82
- cloned_release = Bosh::Workspace::Release.new(data, releases_dir)
83
- cloned_release.update_repo
134
+ context "multiple releases" do
135
+ let(:version) { "11" }
136
+
137
+ before do
138
+ load_release("name" => "bar", "version" => 2, "git" => repo).update_repo
139
+ end
140
+
141
+ it "version 11" do
142
+ release.update_repo
143
+ expect(subject).to match(/foo-11.yml/)
144
+ expect(templates).to_not match(/deployment.yml/)
145
+ end
84
146
  end
85
147
 
86
- it "version 3" do
87
- release.update_repo
88
- expect(subject).to match(/foo-3.yml/)
148
+ context "specific version" do
149
+ let(:version) { "11" }
150
+ before { release.update_repo }
151
+
152
+ it "checks out repo" do
153
+ expect(subject).to match(/foo-11.yml/)
154
+ end
155
+
156
+ it "does not include templates from master" do
157
+ expect(templates).to_not match(/deployment.yml/)
158
+ end
89
159
  end
90
- end
91
160
 
92
- context "multiple releases" do
93
- let(:version) { "11" }
161
+ context "specific version" do
162
+ let(:version) { "2" }
94
163
 
95
- before do
96
- data = { "name" => "bar", "version" => 2, "git" => repo }
97
- other_release = Bosh::Workspace::Release.new(data, releases_dir)
98
- other_release.update_repo
164
+ it "checks out repo" do
165
+ release.update_repo
166
+ expect(subject).to match(/foo-2.yml/)
167
+ end
99
168
  end
100
169
 
101
- it "version 3" do
102
- release.update_repo
103
- expect(subject).to match(/foo-11.yml/)
104
- expect(templates).to_not match(/deployment.yml/)
170
+ context "specific ref with latest release" do
171
+ let(:release_data) do
172
+ {"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
173
+ end
174
+
175
+ it "checks out repo" do
176
+ release.update_repo
177
+ expect(subject).to match(/foo-2.yml/)
178
+ expect(subject).to_not match(/foo-3.yml/)
179
+ end
105
180
  end
106
- end
107
- end
108
181
 
109
- describe "attributes" do
110
- subject { release }
111
- its(:name){ should eq name }
112
- its(:git_uri){ should eq repo }
113
- its(:repo_dir){ should match(/\/#{name}$/) }
114
- its(:manifest_file){ should match(/\/#{name}-#{version}.yml$/) }
115
- its(:manifest){ should match "releases/#{name}-#{version}.yml$" }
116
- its(:name_version){ should eq "#{name}/#{version}" }
117
- its(:version){ should eq version }
118
- end
182
+ context "updated version " do
183
+ let(:version) { "11" }
184
+
185
+ it "checks out file with multiple commits" do
186
+ release.update_repo
187
+ expect(subject).to match(/foo-11.yml/)
188
+ end
189
+ end
190
+
191
+ context "non existing version " do
192
+ let(:version) { "12" }
193
+
194
+ it "raises an error" do
195
+ expect { release.version }.
196
+ to raise_error(/Could not find version/)
197
+ end
198
+ end
199
+
200
+ context "already cloned repo" do
201
+ before do
202
+ load_release("name" => name, "version" => 1, "git" => repo).update_repo
203
+ end
119
204
 
120
- after do
121
- FileUtils.rm_r releases_dir
205
+ it "version 3" do
206
+ release.update_repo
207
+ expect(subject).to match(/foo-3.yml/)
208
+ end
209
+ end
210
+
211
+ context "multiple releases" do
212
+ let(:version) { "11" }
213
+
214
+ before do
215
+ load_release("name" => "bar", "version" => 2, "git" => repo).update_repo
216
+ end
217
+
218
+ it "version 11" do
219
+ release.update_repo
220
+ expect(subject).to match(/foo-11.yml/)
221
+ expect(templates).to_not match(/deployment.yml/)
222
+ end
223
+ end
224
+
225
+ context "new release in already cloned repo" do
226
+ let(:version) { "12" }
227
+
228
+ before do
229
+ load_release("name" => name, "version" => 1, "git" => repo).update_repo
230
+ extracted_asset_dir("foo", "foo-boshrelease-repo-updated.zip")
231
+ end
232
+
233
+ it "version 12" do
234
+ release.update_repo
235
+ expect(subject).to match(/foo-12.yml/)
236
+ end
237
+ end
238
+ end
239
+
240
+ describe "attributes" do
241
+ subject { release }
242
+ its(:name) { should eq name }
243
+ its(:git_url) { should eq repo }
244
+ its(:repo_dir) { should match(/\/#{name}$/) }
245
+ its(:manifest_file) { should match(/\/#{name}-#{version}.yml$/) }
246
+ its(:manifest) { should match "releases/#{name}-#{version}.yml$" }
247
+ its(:name_version) { should eq "#{name}/#{version}" }
248
+ its(:version) { should eq version }
249
+ end
122
250
  end
123
251
  end
@@ -0,0 +1,28 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe Credentials do
3
+ let(:username_password) do
4
+ { "url" => "foo", "username" => "bar", "password" => "baz" }
5
+ end
6
+ let(:ssh_key) do
7
+ { "url" => "bar", "private_key" => "foobarkey" }
8
+ end
9
+
10
+ subject { Credentials.new.validate(credentials) }
11
+
12
+ context "valid credentials" do
13
+ let(:credentials) { [username_password, ssh_key] }
14
+ it { expect { subject }.to_not raise_error }
15
+ end
16
+
17
+ %w(url username password private_key).each do |field_name|
18
+ context "missing #{field_name}" do
19
+ let(:credentials) do
20
+ [username_password, ssh_key].map do |c|
21
+ c.delete_if { |k| k == field_name }
22
+ end
23
+ end
24
+ it { expect { subject }.to raise_error(/doesn't validate/i) }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe DeploymentPatch do
3
+ before do
4
+ allow_any_instance_of(Releases).to receive(:validate).with(:releases)
5
+ allow_any_instance_of(Stemcells).to receive(:validate).with(:stemcells)
6
+ end
7
+
8
+ let(:deployment_patch) do
9
+ {
10
+ "stemcells" => :stemcells,
11
+ "releases" => :releases,
12
+ "templates_ref" => "477d1228a9f27815d6df3ab977235ab26eecbba6"
13
+ }
14
+ end
15
+
16
+ subject { DeploymentPatch.new.validate(deployment_patch) }
17
+
18
+ %w(stemcells releases).each do |field|
19
+ context "missing #{field}" do
20
+ before { deployment_patch.delete field }
21
+ it { expect { subject }.to raise_error(/#{field}.*missing/i) }
22
+ end
23
+ end
24
+
25
+ context "optional templates_ref" do
26
+ before { deployment_patch.delete "templates_ref" }
27
+ it { expect { subject }.to_not raise_error }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,45 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe ProjectDeployment do
3
+ before do
4
+ allow_any_instance_of(Releases).to receive(:validate).with(:releases)
5
+ allow_any_instance_of(Stemcells).to receive(:validate).with(:stemcells)
6
+ end
7
+
8
+ let(:project_deployment) do
9
+ {
10
+ "name" => "foo",
11
+ "director_uuid" => "e55134c3-0a63-47be-8409-c9e53e965d5c",
12
+ "stemcells" => :stemcells,
13
+ "releases" => :releases,
14
+ "templates" => [ "foo/bar.yml" ],
15
+ "meta" => { "foo" => "bar" }
16
+ }
17
+ end
18
+
19
+ subject { ProjectDeployment.new.validate(project_deployment) }
20
+
21
+ %w(name director_uuid releases templates meta stemcells).each do |field|
22
+ context "missing #{field}" do
23
+ before { project_deployment.delete field }
24
+ it { expect { subject }.to raise_error(/#{field}.*missing/i) }
25
+ end
26
+ end
27
+
28
+ context "optional domain_name" do
29
+ before { project_deployment["domain_name"] = "example.com" }
30
+ it { expect { subject }.to_not raise_error }
31
+ end
32
+
33
+ context "director_uuid" do
34
+ context "invalid" do
35
+ before { project_deployment["director_uuid"] = "invalid_uuid" }
36
+ it { expect { subject }.to raise_error(/director_uuid.*doesn't validate/) }
37
+ end
38
+
39
+ context "current" do
40
+ before { project_deployment["director_uuid"] = "current" }
41
+ it { expect { subject }.to_not raise_error }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe Releases do
3
+ let(:release) do
4
+ {"name" => "foo", "version" => 1, "ref" => "cec3ec1", "git" => "example.com/git.git"}
5
+ end
6
+
7
+ subject { Releases.new.validate(releases) }
8
+
9
+ %w(name version git).each do |field_name|
10
+ context "missing #{field_name}" do
11
+ let(:releases) { [release.delete_if { |k| k == field_name }] }
12
+ it { expect { subject }.to raise_error(/#{field_name}.*missing/i) }
13
+ end
14
+ end
15
+
16
+ context "latest version" do
17
+ let(:releases) { release["version"] = "latest"; [release] }
18
+ it { expect { subject }.to_not raise_error }
19
+ end
20
+
21
+ context "invalid version" do
22
+ let(:releases) { release["version"] = "foo"; [release] }
23
+ it { expect { subject }.to raise_error(/version.*doesn't validate/i) }
24
+ end
25
+
26
+ context "optional ref" do
27
+ let(:releases) { [release.delete_if { |k| k == "ref" }] }
28
+ it { expect { subject }.to_not raise_error }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe Stemcells do
3
+ let(:stemcell) do
4
+ {"name" => "foo", "version" => 1}
5
+ end
6
+
7
+ subject { Stemcells.new.validate(stemcells) }
8
+
9
+ %w(name version).each do |field_name|
10
+ context "missing #{field_name}" do
11
+ let(:stemcells) { [stemcell.delete_if { |k| k == field_name }] }
12
+ it { expect { subject }.to raise_error(/#{field_name}.*missing/i) }
13
+ end
14
+ end
15
+
16
+ context "latest version" do
17
+ let(:stemcells) { stemcell["version"] = "latest"; [stemcell] }
18
+ it { expect { subject }.to_not raise_error }
19
+ end
20
+
21
+ context "patch version string" do
22
+ let(:stemcells) { stemcell["version"] = "2719.1"; [stemcell] }
23
+ it { expect { subject }.to_not raise_error }
24
+ end
25
+
26
+ context "patch version float" do
27
+ let(:stemcells) { stemcell["version"] = 2719.1; [stemcell] }
28
+ it { expect { subject }.to_not raise_error }
29
+ end
30
+
31
+ context "invalid version" do
32
+ let(:stemcells) { stemcell["version"] = "foo"; [stemcell] }
33
+ it { expect { subject }.to raise_error(/version.*should match/i) }
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,70 @@
1
+ module Bosh::Workspace
2
+ describe Shell do
3
+ subject { Shell.new(stdout) }
4
+ let(:stdout) { StringIO.new }
5
+
6
+ describe '#run' do
7
+ it 'shells out, prints and returns the output of the command' do
8
+ expect(subject.run('echo hello; echo world')).to eq("hello\nworld")
9
+ expect(stdout.string).to eq("hello\nworld\n")
10
+ end
11
+
12
+ it 'shells out with specified additional env variables' do
13
+ stub_const('ENV', 'SHELL' => '/bin/bash')
14
+ expect(subject.run('env env', env: { 'VAR' => '123' })).to include('VAR=123')
15
+ expect(stdout.string).to include('VAR=123')
16
+ end
17
+
18
+ it 'shells out with specified additional env variables even when SHELL env variable is not available' do
19
+ stub_const('ENV', {})
20
+ expect(subject.run('env env', env: { 'VAR' => '123' })).to include('VAR=123')
21
+ expect(stdout.string).to include('VAR=123')
22
+ end
23
+
24
+ context 'when "output_command" is specified' do
25
+ it 'outputs the command' do
26
+ subject.run('echo 1;echo 2;echo 3;echo 4;echo 5', output_command: true)
27
+ expect(stdout.string).to include('echo 1;echo 2;echo 3;echo 4;echo 5')
28
+ end
29
+ end
30
+
31
+ context 'when "last_number" is specified' do
32
+ it 'tails "last_number" lines of output' do
33
+ cmd = 'echo 1;echo 2;echo 3;echo 4;echo 5'
34
+ expect(subject.run(cmd, last_number: 3)).to eq("3\n4\n5")
35
+ expect(stdout.string).to eq("1\n2\n3\n4\n5\n")
36
+ end
37
+
38
+ it 'outputs the entire output if more lines are requested than generated' do
39
+ cmd = 'echo 1;echo 2;echo 3;echo 4;echo 5'
40
+ expect(subject.run(cmd, last_number: 6)).to eq("1\n2\n3\n4\n5")
41
+ expect(stdout.string).to eq("1\n2\n3\n4\n5\n")
42
+ end
43
+ end
44
+
45
+ context 'when the command fails' do
46
+ it 'raises an error' do
47
+ expect {
48
+ subject.run('false')
49
+ }.to raise_error /Failed: 'false' from /
50
+ end
51
+
52
+ context 'because the working directory has gone missing' do
53
+ it 'fails gracefully with a slightly helpful error message' do
54
+ allow(Dir).to receive(:pwd).and_raise(Errno::ENOENT, 'No such file or directory - getcwd')
55
+ expect {
56
+ subject.run('false')
57
+ }.to raise_error /from a deleted directory/
58
+ end
59
+ end
60
+
61
+ context 'and ignoring failures' do
62
+ it 'raises an error' do
63
+ subject.run('false', ignore_failures: true)
64
+ expect(stdout.string).to match(/continuing anyway/)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
data/spec/spec_helper.rb CHANGED
@@ -19,8 +19,11 @@ require "archive/zip"
19
19
  require "cli"
20
20
 
21
21
  require "bosh/workspace"
22
+ require "bosh/workspace/tasks"
22
23
 
23
24
  RSpec.configure do |config|
25
+ config.filter_run focus: true
26
+ config.run_all_when_everything_filtered = true
24
27
  config.raise_errors_for_deprecations!
25
28
  config.expect_with :rspec do |c|
26
29
  c.syntax = :expect
@@ -28,7 +31,7 @@ RSpec.configure do |config|
28
31
  end
29
32
 
30
33
  # load all files in spec/support/* (but not lower down)
31
- Dir[File.dirname(__FILE__) + '/support/*'].each do |path|
34
+ Dir[File.dirname(__FILE__) + '/support/*/*.rb'].each do |path|
32
35
  require path unless File.directory?(path)
33
36
  end
34
37
 
@@ -81,9 +84,12 @@ end
81
84
  def extracted_asset_dir(name, *path)
82
85
  zipped_file = asset_dir(*path)
83
86
  target_dir = File.expand_path("../../tmp/#{name}", __FILE__)
84
- unless File.directory?(target_dir)
85
- FileUtils.mkdir_p(target_dir)
86
- Archive::Zip.extract(zipped_file, target_dir)
87
- end
87
+ FileUtils.rm_rf(target_dir) if File.exist?(target_dir)
88
+ FileUtils.mkdir_p(target_dir)
89
+ Archive::Zip.extract(zipped_file, target_dir)
88
90
  target_dir
89
91
  end
92
+
93
+ def project_root
94
+ File.expand_path('../../', __FILE__)
95
+ end
@@ -0,0 +1,37 @@
1
+ require "rake"
2
+
3
+ shared_context "rake" do
4
+ let(:rake) { Rake::Application.new }
5
+ let(:task_name) { self.class.top_level_description }
6
+ let(:task_path) { "lib/bosh/workspace/tasks/#{task_name.split(":").first}" }
7
+
8
+ def loaded_files_excluding_current_rake_file
9
+ $".reject { |file| file == File.join(project_root, "#{task_path}.rake") }
10
+ end
11
+
12
+ def clear_main_instance_vars
13
+ TOPLEVEL_BINDING.eval('self').instance_variables.each do |var|
14
+ TOPLEVEL_BINDING.eval('self').remove_instance_variable(var)
15
+ end
16
+ end
17
+
18
+ def setup_already_invoked_tasks
19
+ if defined? already_invoked_tasks
20
+ rake.instance_variable_get(:@tasks).each do |name, task|
21
+ if already_invoked_tasks.include? name
22
+ task.instance_variable_set(:@already_invoked, true)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ before do
29
+ Rake.application = rake
30
+ Rake.application.rake_require(task_path, [project_root], loaded_files_excluding_current_rake_file)
31
+ setup_already_invoked_tasks
32
+ end
33
+
34
+ after do
35
+ clear_main_instance_vars
36
+ end
37
+ end