bosh-workspace 0.7.0 → 0.8.0
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 +5 -13
- data/.ruby-version +1 -1
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/Guardfile +2 -2
- data/README.md +78 -39
- data/Rakefile +4 -0
- data/bosh-workspace.gemspec +4 -1
- data/lib/bosh/cli/commands/prepare.rb +74 -0
- data/lib/bosh/cli/commands/{01_make_manifest.rb → project_deployment.rb} +4 -26
- data/lib/bosh/workspace.rb +7 -3
- data/lib/bosh/workspace/helpers/dns_helper.rb +72 -0
- data/lib/bosh/workspace/helpers/project_deployment_helper.rb +8 -3
- data/lib/bosh/workspace/helpers/release_helper.rb +33 -0
- data/lib/bosh/workspace/helpers/spiff_helper.rb +1 -1
- data/lib/bosh/workspace/helpers/stemcell_helper.rb +45 -0
- data/lib/bosh/workspace/manifest_builder.rb +10 -25
- data/lib/bosh/workspace/project_deployment.rb +77 -0
- data/lib/bosh/workspace/release.rb +41 -33
- data/lib/bosh/workspace/stemcell.rb +23 -0
- data/lib/bosh/workspace/stub_file.rb +44 -0
- data/lib/bosh/workspace/version.rb +1 -1
- data/spec/assets/dns/job-properties.yml +22 -0
- data/spec/assets/dns/jobs.yml +18 -0
- data/spec/assets/dns/networks-manual.yml +19 -0
- data/spec/assets/dns/networks-no-manual.yml +18 -0
- data/spec/assets/dns/properties.yml +29 -0
- data/spec/assets/foo-boshrelease-repo.zip +0 -0
- data/spec/commands/prepare_spec.rb +99 -0
- data/spec/commands/{command_make_manifest_spec.rb → project_deployment_spec.rb} +4 -23
- data/spec/helpers/dns_helper_spec.rb +59 -0
- data/spec/helpers/project_deployment_helper_spec.rb +24 -23
- data/spec/helpers/release_helper_spec.rb +76 -0
- data/spec/helpers/spiff_helper_spec.rb +2 -2
- data/spec/helpers/stemcell_helper_spec.rb +89 -0
- data/spec/manifest_builder_spec.rb +24 -45
- data/spec/project_deployment_spec.rb +157 -0
- data/spec/release_spec.rb +39 -18
- data/spec/spec_helper.rb +9 -3
- data/spec/stemcell_spec.rb +28 -0
- data/spec/stub_file_spec.rb +74 -0
- metadata +90 -22
- data/lib/bosh/workspace/deployment_manifest.rb +0 -67
- data/lib/bosh/workspace/release_manager.rb +0 -14
- data/spec/deployment_manifest_spec.rb +0 -93
- data/spec/release_manager_spec.rb +0 -17
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
networks:
|
3
|
+
- name: floating
|
4
|
+
type: vip
|
5
|
+
cloud_properties: {}
|
6
|
+
- name: default
|
7
|
+
type: manual
|
8
|
+
subnets:
|
9
|
+
- name: private
|
10
|
+
range: 10.0.0.0/24
|
11
|
+
gateway: 10.0.0.254
|
12
|
+
reserved:
|
13
|
+
- 10.0.0.1 - 10.0.0.10
|
14
|
+
static:
|
15
|
+
- 10.0.0.50 - 10.0.0.100
|
16
|
+
cloud_properties:
|
17
|
+
net_id: 1202c961-504d-4afb-b044-623787746307
|
18
|
+
|
19
|
+
jobs: []
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
networks:
|
3
|
+
- name: floating
|
4
|
+
type: vip
|
5
|
+
cloud_properties: {}
|
6
|
+
- name: default
|
7
|
+
subnets:
|
8
|
+
- name: private
|
9
|
+
range: 10.0.0.0/24
|
10
|
+
gateway: 10.0.0.254
|
11
|
+
reserved:
|
12
|
+
- 10.0.0.1 - 10.0.0.10
|
13
|
+
static:
|
14
|
+
- 10.0.0.50 - 10.0.0.100
|
15
|
+
cloud_properties:
|
16
|
+
net_id: 1202c961-504d-4afb-b044-623787746307
|
17
|
+
|
18
|
+
jobs: []
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: foo
|
2
|
+
|
3
|
+
networks:
|
4
|
+
- name: default
|
5
|
+
type: manual
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
- name: first_job_az1
|
9
|
+
networks:
|
10
|
+
- name: default
|
11
|
+
static_ips:
|
12
|
+
- 10.0.0.50
|
13
|
+
|
14
|
+
- name: second_job_az1
|
15
|
+
networks:
|
16
|
+
- name: default
|
17
|
+
static_ips:
|
18
|
+
- 10.0.0.51
|
19
|
+
- 10.0.0.52
|
20
|
+
|
21
|
+
properties:
|
22
|
+
job1:
|
23
|
+
foo: bar
|
24
|
+
address: 10.0.0.50
|
25
|
+
job2:
|
26
|
+
machines:
|
27
|
+
- 10.0.0.51
|
28
|
+
- 10.0.0.52
|
29
|
+
|
Binary file
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require "bosh/cli/commands/prepare"
|
2
|
+
|
3
|
+
describe Bosh::Cli::Command::Prepare do
|
4
|
+
describe "#prepare" do
|
5
|
+
let(:command) { Bosh::Cli::Command::Prepare.new }
|
6
|
+
let(:release) do
|
7
|
+
instance_double("Bosh::Workspace::Release",
|
8
|
+
name: "foo", version: "1", repo_dir: ".releases/foo",
|
9
|
+
name_version: "foo/1", manifest_file: "releases/foo-1.yml")
|
10
|
+
end
|
11
|
+
let(:stemcell) do
|
12
|
+
instance_double("Bosh::Workspace::Stemcell",
|
13
|
+
name: "bar", version: "2", name_version: "bar/2",
|
14
|
+
file: ".stemcesll/bar-2.tgz", file_name: "bar-2.tgz")
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
command.stub(:require_project_deployment)
|
19
|
+
command.stub(:auth_required)
|
20
|
+
command.stub(:project_deployment_releases).and_return(releases)
|
21
|
+
command.stub(:project_deployment_stemcells).and_return(stemcells)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "prepare_release(s/_repos)" do
|
25
|
+
let(:releases) { [ release ] }
|
26
|
+
let(:stemcells) { [] }
|
27
|
+
|
28
|
+
before do
|
29
|
+
release.should_receive(:update_repo)
|
30
|
+
command.should_receive(:release_uploaded?)
|
31
|
+
.with(release.name, release.version).and_return(release_uploaded)
|
32
|
+
end
|
33
|
+
|
34
|
+
context "release uploaded" do
|
35
|
+
let(:release_uploaded) { true }
|
36
|
+
|
37
|
+
it "does not upload the release" do
|
38
|
+
command.should_not_receive(:release_upload)
|
39
|
+
command.prepare
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "release not uploaded" do
|
44
|
+
let(:release_uploaded) { false }
|
45
|
+
|
46
|
+
it "does not upload the release" do
|
47
|
+
command.should_receive(:release_upload).with(release.manifest_file)
|
48
|
+
command.prepare
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "prepare_stemcells" do
|
54
|
+
let(:releases) { [] }
|
55
|
+
let(:stemcells) { [ stemcell ] }
|
56
|
+
|
57
|
+
before do
|
58
|
+
command.should_receive(:stemcell_uploaded?)
|
59
|
+
.with(stemcell.name, stemcell.version).and_return(stemcell_uploaded)
|
60
|
+
end
|
61
|
+
|
62
|
+
context "stemcell uploaded" do
|
63
|
+
let(:stemcell_uploaded) { true }
|
64
|
+
|
65
|
+
it "does not upload the stemcell" do
|
66
|
+
command.should_not_receive(:stemcell_download)
|
67
|
+
command.should_not_receive(:stemcell_upload)
|
68
|
+
command.prepare
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "stemcell not uploaded" do
|
73
|
+
let(:stemcell_uploaded) { false }
|
74
|
+
|
75
|
+
before { stemcell.should_receive(:downloaded?).and_return(stemcell_downloaded) }
|
76
|
+
|
77
|
+
context "stemcell downloaded" do
|
78
|
+
let(:stemcell_downloaded) { true }
|
79
|
+
|
80
|
+
it "does not upload the stemcell" do
|
81
|
+
command.should_not_receive(:stemcell_download)
|
82
|
+
command.should_receive(:stemcell_upload).with(stemcell.file)
|
83
|
+
command.prepare
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "stemcell downloaded" do
|
88
|
+
let(:stemcell_downloaded) { false }
|
89
|
+
|
90
|
+
it "does not upload the stemcell" do
|
91
|
+
command.should_receive(:stemcell_download).with(stemcell.file_name)
|
92
|
+
command.should_receive(:stemcell_upload).with(stemcell.file)
|
93
|
+
command.prepare
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require "bosh/cli/commands/
|
1
|
+
require "bosh/cli/commands/project_deployment"
|
2
2
|
|
3
|
-
describe Bosh::Cli::Command::
|
4
|
-
let(:command) { Bosh::Cli::Command::
|
3
|
+
describe Bosh::Cli::Command::ProjectDeployment do
|
4
|
+
let(:command) { Bosh::Cli::Command::ProjectDeployment.new }
|
5
5
|
let(:project_deployment) do
|
6
|
-
instance_double("Bosh::
|
6
|
+
instance_double("Bosh::Workspace::DeploymentManifest")
|
7
7
|
end
|
8
8
|
|
9
9
|
let(:deployment_cmd) { instance_double("Bosh::Cli::Command::Deployment") }
|
@@ -56,25 +56,6 @@ describe Bosh::Cli::Command::Manifests do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
describe "#prepare" do
|
60
|
-
subject { command.prepare }
|
61
|
-
let(:releases) { ["foo", "bar"] }
|
62
|
-
let(:release_manager) { instance_double("Bosh::Manifests::ReleaseManager") }
|
63
|
-
let(:work_dir) { asset_dir("manifests-repo") }
|
64
|
-
|
65
|
-
it "resolves deployment requirements" do
|
66
|
-
command.should_receive(:require_project_deployment)
|
67
|
-
command.should_receive(:auth_required)
|
68
|
-
command.should_receive(:project_deployment).and_return(project_deployment)
|
69
|
-
project_deployment.should_receive(:releases).and_return(releases)
|
70
|
-
command.should_receive(:work_dir).and_return(work_dir)
|
71
|
-
Bosh::Manifests::ReleaseManager.should_receive(:new)
|
72
|
-
.with(releases, work_dir).and_return(release_manager)
|
73
|
-
release_manager.should_receive(:update_release_repos)
|
74
|
-
subject
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
59
|
describe "deploy" do
|
79
60
|
subject { command.deploy }
|
80
61
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
describe Bosh::Workspace::DnsHelper do
|
2
|
+
describe ".transform" do
|
3
|
+
subject do
|
4
|
+
Bosh::Workspace::DnsHelper.transform(generated_manifest, domain_name)
|
5
|
+
YAML.load(IO.read(generated_manifest))
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:generated_manifest) { get_tmp_file_path(content) }
|
9
|
+
let(:domain_name) { "microbosh" }
|
10
|
+
|
11
|
+
context "networks" do
|
12
|
+
let(:content) { asset_file("dns/networks-manual.yml") }
|
13
|
+
|
14
|
+
it "replaces manual networks" do
|
15
|
+
expect(subject["networks"][1]["type"]).to eq "dynamic"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "no manual networks" do
|
20
|
+
let(:content) { asset_file("dns/networks-no-manual.yml") }
|
21
|
+
|
22
|
+
it "raises an error" do
|
23
|
+
expect { subject }.to raise_error /Missing manual network/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "jobs" do
|
28
|
+
let(:content) { asset_file("dns/jobs.yml") }
|
29
|
+
|
30
|
+
it "removes static_ips of jobs with manual networks" do
|
31
|
+
expect(subject["jobs"][0]["networks"][0]).to_not include "static_ips"
|
32
|
+
expect(subject["jobs"][1]["networks"][0]).to_not include "static_ips"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "properties" do
|
37
|
+
let(:content) { asset_file("dns/properties.yml") }
|
38
|
+
|
39
|
+
it "replaces ips with domains while keeping properties structure" do
|
40
|
+
expect(subject["properties"]["job1"]["address"])
|
41
|
+
.to eq "0.first-job-az1.default.foo.microbosh"
|
42
|
+
expect(subject["properties"]["job1"]["foo"]).to eq "bar"
|
43
|
+
expect(subject["properties"]["job2"]["machines"])
|
44
|
+
.to eq ["0.second-job-az1.default.foo.microbosh",
|
45
|
+
"1.second-job-az1.default.foo.microbosh"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "job properties" do
|
50
|
+
let(:content) { asset_file("dns/job-properties.yml") }
|
51
|
+
|
52
|
+
it "replaces ips with domains while keeping properties structure" do
|
53
|
+
expect(subject["jobs"][1]["properties"]["job1"]["address"])
|
54
|
+
.to eq "0.first-job-az1.default.foo.microbosh"
|
55
|
+
expect(subject["jobs"][1]["properties"]["job1"]["foo"]).to eq "bar"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
describe Bosh::
|
2
|
-
class
|
3
|
-
include Bosh::
|
1
|
+
describe Bosh::Workspace::ProjectDeploymentHelper do
|
2
|
+
class ProjectDeploymentHelperTester
|
3
|
+
include Bosh::Workspace::ProjectDeploymentHelper
|
4
4
|
|
5
5
|
attr_reader :director, :deployment
|
6
6
|
|
@@ -12,14 +12,17 @@ describe Bosh::Manifests::ProjectDeploymentHelper do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
subject { project_deployment_helper }
|
15
|
-
let(:project_deployment_helper)
|
15
|
+
let(:project_deployment_helper) do
|
16
|
+
ProjectDeploymentHelperTester.new(director, deployment, project_deployment)
|
17
|
+
end
|
16
18
|
let(:deployment) { nil }
|
17
19
|
let(:director) { instance_double('Bosh::Cli::Client::Director') }
|
18
20
|
let(:work_dir) { asset_dir("manifests-repo") }
|
19
|
-
let(:project_deployment) { instance_double("
|
21
|
+
let(:project_deployment) { instance_double("ProjectDeployment") }
|
20
22
|
|
21
23
|
describe "project_deployment?" do
|
22
24
|
subject { project_deployment_helper.project_deployment? }
|
25
|
+
let(:project_deployment_helper) { ProjectDeploymentHelperTester.new(director, deployment) }
|
23
26
|
let(:deployment) { File.join work_dir, deployment_path }
|
24
27
|
|
25
28
|
context "deployment" do
|
@@ -40,11 +43,12 @@ describe Bosh::Manifests::ProjectDeploymentHelper do
|
|
40
43
|
end
|
41
44
|
|
42
45
|
describe "#project_deployment(=)" do
|
46
|
+
let(:project_deployment_helper) { ProjectDeploymentHelperTester.new(director, deployment) }
|
43
47
|
let(:deployment) { File.join work_dir, deployment_path }
|
44
48
|
let(:deployment_path) { "deployments/foo.yml" }
|
45
49
|
|
46
50
|
before do
|
47
|
-
Bosh::
|
51
|
+
Bosh::Workspace::ProjectDeployment.should_receive(:new)
|
48
52
|
.with(deployment).and_return(project_deployment)
|
49
53
|
end
|
50
54
|
|
@@ -76,6 +80,8 @@ describe Bosh::Manifests::ProjectDeploymentHelper do
|
|
76
80
|
end
|
77
81
|
|
78
82
|
describe "#require_project_deployment" do
|
83
|
+
let(:project_deployment_helper) { ProjectDeploymentHelperTester.new(director, deployment) }
|
84
|
+
|
79
85
|
before do
|
80
86
|
subject.should_receive(:project_deployment?)
|
81
87
|
.and_return(:is_project_deployment)
|
@@ -93,16 +99,13 @@ describe Bosh::Manifests::ProjectDeploymentHelper do
|
|
93
99
|
let(:deployment) { "foo" }
|
94
100
|
let(:is_project_deployment) { false }
|
95
101
|
it "raises and error" do
|
96
|
-
expect { subject.require_project_deployment }.to raise_error
|
102
|
+
expect { subject.require_project_deployment }.to raise_error(/foo/)
|
97
103
|
end
|
98
104
|
end
|
99
105
|
end
|
100
106
|
|
101
107
|
describe "#create_placeholder_deployment" do
|
102
108
|
subject { project_deployment_helper.create_placeholder_deployment }
|
103
|
-
let(:project_deployment_helper) do
|
104
|
-
HelperTester.new(director, deployment, project_deployment)
|
105
|
-
end
|
106
109
|
let(:deployment) { "deployments/bar.yml" }
|
107
110
|
let(:file) { instance_double('File') }
|
108
111
|
let(:merged_file) { ".deployments/bar.yml" }
|
@@ -121,38 +124,36 @@ describe Bosh::Manifests::ProjectDeploymentHelper do
|
|
121
124
|
end
|
122
125
|
|
123
126
|
describe "#validate_project_deployment" do
|
124
|
-
let(:project_deployment_helper) do
|
125
|
-
HelperTester.new(director, deployment, project_deployment)
|
126
|
-
end
|
127
|
-
|
128
127
|
it "raises an error" do
|
129
128
|
project_deployment.should_receive(:valid?).and_return(false)
|
130
129
|
project_deployment.should_receive(:errors).and_return(["foo"])
|
131
130
|
project_deployment.should_receive(:file).and_return(["foo.yml"])
|
132
|
-
expect { subject.validate_project_deployment }.to raise_error
|
131
|
+
expect { subject.validate_project_deployment }.to raise_error(/foo/)
|
133
132
|
end
|
134
133
|
end
|
135
134
|
|
136
135
|
describe "#build_project_deployment" do
|
137
136
|
subject { project_deployment_helper.build_project_deployment }
|
138
|
-
let(:
|
139
|
-
|
140
|
-
end
|
137
|
+
let(:domain_name) { "bosh" }
|
138
|
+
let(:merged_file) { "foo/bar" }
|
141
139
|
|
142
140
|
it "builds project deployment manifest" do
|
143
141
|
project_deployment_helper.should_receive(:resolve_director_uuid)
|
144
142
|
project_deployment_helper.should_receive(:work_dir).and_return(work_dir)
|
145
|
-
|
143
|
+
project_deployment.should_receive(:domain_name).and_return(domain_name)
|
144
|
+
project_deployment.should_receive(:merged_file).and_return(merged_file)
|
145
|
+
|
146
|
+
Bosh::Workspace::ManifestBuilder.should_receive(:build)
|
146
147
|
.with(project_deployment, work_dir)
|
148
|
+
Bosh::Workspace::DnsHelper.should_receive(:transform)
|
149
|
+
.with(merged_file, domain_name)
|
150
|
+
|
147
151
|
subject
|
148
152
|
end
|
149
153
|
end
|
150
154
|
|
151
155
|
describe "#resolve_director_uuid" do
|
152
156
|
subject { project_deployment_helper.resolve_director_uuid }
|
153
|
-
let(:project_deployment_helper) do
|
154
|
-
HelperTester.new(director, deployment, project_deployment)
|
155
|
-
end
|
156
157
|
let(:status) { { "uuid" => current_uuid, "cpi" => cpi } }
|
157
158
|
let(:current_uuid) { "current-uuid" }
|
158
159
|
|
@@ -184,7 +185,7 @@ describe Bosh::Manifests::ProjectDeploymentHelper do
|
|
184
185
|
let(:uuid) { "current" }
|
185
186
|
let(:cpi) { "not-warden" }
|
186
187
|
it "raises an error" do
|
187
|
-
expect { subject }.to raise_error
|
188
|
+
expect { subject }.to raise_error(/may not be used in production/)
|
188
189
|
end
|
189
190
|
end
|
190
191
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
describe Bosh::Workspace::ReleaseHelper do
|
2
|
+
class ReleaseHelperTester
|
3
|
+
include Bosh::Workspace::ReleaseHelper
|
4
|
+
|
5
|
+
attr_reader :director, :work_dir
|
6
|
+
|
7
|
+
def initialize(director, work_dir)
|
8
|
+
@director = director
|
9
|
+
@work_dir = work_dir
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { release_helper }
|
14
|
+
let(:release_helper) { ReleaseHelperTester.new(director, work_dir) }
|
15
|
+
let(:director) { instance_double('Bosh::Cli::Client::Director') }
|
16
|
+
let(:work_dir) { asset_dir("manifests-repo") }
|
17
|
+
|
18
|
+
describe "#release_upload" do
|
19
|
+
let(:release_cmd) { instance_double("Bosh::Cli::Command::Release") }
|
20
|
+
before { Bosh::Cli::Command::Release.stub(:new).and_return(release_cmd) }
|
21
|
+
|
22
|
+
let(:manifest_file) { "foo-1.yml." }
|
23
|
+
subject { release_helper.release_upload(manifest_file) }
|
24
|
+
|
25
|
+
it "uploads release" do
|
26
|
+
release_cmd.should_receive(:upload).with(manifest_file)
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#release_uploaded?" do
|
32
|
+
let(:releases) { { "versions" => %w(1 2 3) } }
|
33
|
+
subject { release_helper.release_uploaded?("foo", version) }
|
34
|
+
before { director.should_receive(:get_release).with("foo").and_return(releases) }
|
35
|
+
|
36
|
+
context "release exists" do
|
37
|
+
let(:version) { 2 }
|
38
|
+
it { should be_true }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "release not found" do
|
42
|
+
let(:version) { "8" }
|
43
|
+
it { should be_false }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#release_dir" do
|
48
|
+
let(:releases_dir) { File.join(work_dir, ".releases") }
|
49
|
+
subject { release_helper.releases_dir }
|
50
|
+
|
51
|
+
before { FileUtils.should_receive(:mkdir_p).once.with(releases_dir).and_return([releases_dir]) }
|
52
|
+
|
53
|
+
it { should eq releases_dir }
|
54
|
+
|
55
|
+
it "memoizes" do
|
56
|
+
subject
|
57
|
+
expect(subject).to eq releases_dir
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#project_deployment_releases" do
|
62
|
+
subject { release_helper.project_deployment_releases }
|
63
|
+
let(:release) { instance_double("Bosh::Workspace::Release") }
|
64
|
+
let(:release_data) { { name: "foo" } }
|
65
|
+
let(:releases) { [release_data, release_data] }
|
66
|
+
|
67
|
+
before { release_helper.stub_chain("project_deployment.releases").and_return(releases) }
|
68
|
+
|
69
|
+
it "inits releases once" do
|
70
|
+
Bosh::Workspace::Release.should_receive(:new).twice
|
71
|
+
.with(release_data, /\/.releases/).and_return(release)
|
72
|
+
subject
|
73
|
+
expect(subject).to eq [release, release]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|