bosh-workspace 0.8.5 → 0.9.0.rc1

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 (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
@@ -0,0 +1,171 @@
1
+ module Bosh::Workspace
2
+ describe DeploymentPatch do
3
+ let(:stemcells) { [{ 'name' => 'foo', 'version' => 1 }] }
4
+ let(:releases) { [{ 'name' => 'bar', 'version' => 2 }] }
5
+ let(:templates_dir) do
6
+ home = extracted_asset_dir("home", "foo-boshworkspace.zip")
7
+ workspace = File.join(home, "foo-boshworkspace")
8
+ Dir[File.join(workspace, ".git/**/config")].each do |c|
9
+ IO.write(c, IO.read(c).gsub(/(\/U.+tmp)/, home))
10
+ end
11
+ File.join(workspace, "templates")
12
+ end
13
+ let(:templates_ref) { 'bb802816a44d0fd23fd0120f4fdd42578089d025' }
14
+ let(:patch) { DeploymentPatch.new(stemcells, releases, templates_ref) }
15
+ let(:patch_yaml_data) { patch_data.to_yaml }
16
+ let(:deployment_file) { get_tmp_file_path deployment.to_yaml }
17
+ let(:patch_data) do
18
+ { "stemcells" => stemcells, "releases" => releases, "templates_ref" => templates_ref }
19
+ end
20
+ let(:deployment) do
21
+ {
22
+ 'name' => 'foo',
23
+ 'stemcells' => stemcells,
24
+ 'releases' => releases,
25
+ 'templates' => [ 'foo/bar.yml' ],
26
+ 'meta' => { 'foo' => 'bar' }
27
+ }
28
+ end
29
+
30
+ describe '#create' do
31
+ subject { DeploymentPatch.create deployment_file, templates_dir }
32
+
33
+ context "with templates submodule" do
34
+ its(:stemcells) { should eq stemcells }
35
+ its(:releases) { should eq releases }
36
+ its(:templates_ref) { should eq templates_ref }
37
+ end
38
+
39
+ context "without templates submodule" do
40
+ let(:templates_dir) do
41
+ asset_dir("manifests-repo/templates")
42
+ end
43
+
44
+ it "ignores templates directory" do
45
+ expect(subject.templates_ref).to be_nil
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '.from_file' do
51
+ subject { DeploymentPatch.from_file get_tmp_file_path(patch_yaml_data) }
52
+ its(:stemcells) { should eq stemcells }
53
+ its(:releases) { should eq releases }
54
+ its(:templates_ref) { should eq templates_ref }
55
+ end
56
+
57
+ describe '#perform_validation' do
58
+ context "valid" do
59
+ it "validates" do
60
+ allow_any_instance_of(Schemas::DeploymentPatch)
61
+ .to receive(:validate).with(patch_data)
62
+ expect(patch).to be_valid
63
+ end
64
+ end
65
+
66
+ context "invalid" do
67
+ it "has errors" do
68
+ allow_any_instance_of(Schemas::DeploymentPatch)
69
+ .to receive(:validate).with(patch_data)
70
+ .and_raise(Membrane::SchemaValidationError.new("foo"))
71
+ expect(patch).to_not be_valid
72
+ expect(patch.errors).to include "foo"
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '#to_hash' do
78
+ subject { patch.to_hash }
79
+ it { should eq patch_data }
80
+
81
+ context "without templates_ref" do
82
+ let(:templates_ref) { nil }
83
+ before { patch_data.delete "templates_ref" }
84
+ it { should eq patch_data }
85
+ end
86
+ end
87
+
88
+ describe '#to_yaml' do
89
+ subject { patch.to_yaml }
90
+ it { should eq patch_yaml_data }
91
+ end
92
+
93
+ describe '#to_file' do
94
+ let(:patch_file) { get_tmp_file_path '{}' }
95
+
96
+ it 'writes to file' do
97
+ patch.to_file(patch_file)
98
+ expect(IO.read(patch_file)).to eq patch_yaml_data
99
+ end
100
+ end
101
+
102
+ describe '#apply' do
103
+ let(:templates_ref) { '505b82012133673a9150d4e83aede1a07598154b' }
104
+ let(:deployment) { { "stemcells" => [], "releases" => [] } }
105
+ let(:deployment_new) { { "stemcells" => stemcells, "releases" => releases } }
106
+ let(:template_files) { Dir.entries(templates_dir) }
107
+
108
+ subject { patch.apply(deployment_file, templates_dir) }
109
+
110
+ it 'applies changes' do
111
+ subject
112
+ expect(IO.read(deployment_file)).to eq deployment_new.to_yaml
113
+ expect(template_files).to include "bar.yml"
114
+ end
115
+
116
+ context "without templates_ref" do
117
+ let(:templates_ref) { nil }
118
+ it 'leaves templates dir as is' do
119
+ subject
120
+ expect(template_files).to include "foo.yml"
121
+ expect(template_files).to_not include "bar.yml"
122
+ end
123
+ end
124
+ end
125
+
126
+ describe '#changes' do
127
+ context 'with changes' do
128
+ let(:new_patch) do
129
+ DeploymentPatch.new(
130
+ [{ 'name' => 'foo', 'version' => 2 }, { 'name' => 'baz', 'version' => 1 }],
131
+ [{ 'name' => 'qux', 'version' => 3 }],
132
+ 'e598fece364ba7447b2e897d71d7008f8390fb86'
133
+ )
134
+ end
135
+ subject { patch.changes(new_patch) }
136
+
137
+ its([:stemcells]) { should eq "changed foo 1 2, added baz 1" }
138
+ its([:releases]) { should eq "removed bar 2, added qux 3" }
139
+ its([:templates_ref]) { should eq "changed bb80281 e598fec" }
140
+
141
+ context 'without templates_ref' do
142
+ subject { patch.changes(new_patch) }
143
+ let(:templates_ref) { nil }
144
+
145
+ its([:stemcells]) { should eq "changed foo 1 2, added baz 1" }
146
+ its([:releases]) { should eq "removed bar 2, added qux 3" }
147
+ its([:templates_ref]) { should be_nil }
148
+ end
149
+ end
150
+
151
+ context 'without changes' do
152
+ subject { patch.changes(patch) }
153
+ it { should be_a(Hash) }
154
+ it { should be_empty }
155
+ end
156
+ end
157
+
158
+ describe '#changes?' do
159
+ context 'with changes' do
160
+ let(:new_patch) { DeploymentPatch.new(stemcells, releases, 'foo') }
161
+ subject { patch.changes?(new_patch) }
162
+ it { should be true }
163
+ end
164
+
165
+ context 'without changes' do
166
+ subject { patch.changes?(patch) }
167
+ it { should be false }
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,160 @@
1
+ module Bosh::Workspace
2
+ describe GitCredenialsHelper do
3
+ class GitCredenialsHelperTester
4
+ include Bosh::Workspace::GitCredenialsHelper
5
+
6
+ attr_reader :work_dir
7
+
8
+ def initialize(work_dir)
9
+ @work_dir = work_dir
10
+ end
11
+ end
12
+
13
+ let(:work_dir) { asset_dir("manifests-repo") }
14
+ let(:url) { "foo/bar.git" }
15
+ let(:dir) { File.join(work_dir, '.releases', 'foo') }
16
+ let(:repo) { instance_double 'Rugged::Repository' }
17
+ let(:remote) { instance_double 'Rugged::Remote', url: url }
18
+
19
+ before do
20
+ allow(Rugged::Repository).to receive(:new).with(dir).and_return(repo)
21
+ allow(File).to receive(:exist?).with(dir).and_return(dir_exist)
22
+ allow(repo).to receive_message_chain("remotes.[]").and_return(remote)
23
+ allow(repo).to receive_message_chain("remotes.create_anonymous")
24
+ .with(url).and_return(remote)
25
+ allow(remote).to receive(:check_connection).with(:fetch, Hash)
26
+ .and_return(!auth_required, credentials_auth_valid)
27
+ allow(repo).to receive(:checkout).with(/origin\/HEAD/, strategy: :force)
28
+ end
29
+
30
+ def expect_no_credentials
31
+ expect(repo).to receive(:fetch).with('origin', Array, {})
32
+ end
33
+
34
+ let(:dir_exist) { true }
35
+ let(:auth_required) { false }
36
+ let(:credentials_auth_valid) { true }
37
+
38
+ describe "fetch_repo" do
39
+ subject do
40
+ GitCredenialsHelperTester.new(work_dir).fetch_repo(dir)
41
+ end
42
+
43
+ context "with existing repo" do
44
+ it do
45
+ expect_no_credentials
46
+ subject
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "fetch_or_clone_repo" do
52
+ subject do
53
+ GitCredenialsHelperTester.new(work_dir).fetch_or_clone_repo(dir, url)
54
+ end
55
+
56
+ context "with existing repo" do
57
+ it do
58
+ expect_no_credentials
59
+ subject
60
+ end
61
+ end
62
+
63
+ context "repo does not yet exist" do
64
+ let(:dir_exist) { false }
65
+
66
+ it "initializes a new repository and sets up a remote" do
67
+ expect(Rugged::Repository).to receive(:init_at).with(dir)
68
+ .and_return(repo)
69
+ expect(repo).to receive_message_chain("remotes.create")
70
+ .with('origin', url)
71
+ expect_no_credentials
72
+ subject
73
+ end
74
+ end
75
+
76
+ context "repo requires authentication" do
77
+ let(:auth_required) { true }
78
+ let(:credentials_file_exist) { true }
79
+ let(:credentials_valid) { true }
80
+ let(:credentials) { instance_double "Bosh::Workspace::Credentials" }
81
+ let(:creds_hash) { {} }
82
+
83
+ def expect_credentials(credentials)
84
+ expect(repo).to receive(:fetch)
85
+ .with('origin', Array, credentials: credentials)
86
+ end
87
+
88
+ before do
89
+ allow(File).to receive(:exist?).with(/.credentials.yml/)
90
+ .and_return(credentials_file_exist)
91
+ allow(Bosh::Workspace::Credentials).to receive(:new)
92
+ .with(/.credentials.yml/).and_return(credentials)
93
+ allow(credentials).to receive(:valid?).and_return(credentials_valid)
94
+ allow(credentials).to receive(:find_by_url)
95
+ .with(url).and_return(creds_hash)
96
+ end
97
+
98
+ context "with sshkey" do
99
+ let(:creds_hash) { { private_key: "foobarkey" } }
100
+
101
+ it "uses a key" do
102
+ expect(Rugged::Credentials::SshKey).to receive(:new) do |args|
103
+ expect(IO.read(args[:privatekey])).to eq "foobarkey"
104
+ :ssh_credentials
105
+ end
106
+ expect_credentials :ssh_credentials
107
+ subject
108
+ end
109
+ end
110
+
111
+ context "with username/password" do
112
+ let(:creds_hash) { { username: "foo", password: "bar" } }
113
+
114
+ it "uses a username/password" do
115
+ expect(Rugged::Credentials::UserPassword).to receive(:new) do |args|
116
+ expect(args[:username]).to eq "foo"
117
+ expect(args[:password]).to eq "bar"
118
+ :user_pw_credentials
119
+ end
120
+ expect_credentials :user_pw_credentials
121
+ subject
122
+ end
123
+ end
124
+
125
+ context "with invalid credentials" do
126
+ let(:credentials_auth_valid) { false }
127
+
128
+ it "raises and error" do
129
+ expect { subject }.to raise_error /invalid credentials/i
130
+ end
131
+ end
132
+
133
+ context "without credentials file" do
134
+ let(:credentials_file_exist) { false }
135
+
136
+ it "raises and error" do
137
+ expect { subject }.to raise_error /credentials file does not exist/i
138
+ end
139
+ end
140
+
141
+ context "with invalid credentials file" do
142
+ let(:credentials_valid) { false }
143
+
144
+ it "raises and error" do
145
+ expect(credentials).to receive(:errors) { ["fooerror"] }
146
+ expect { subject }.to raise_error /not valid/
147
+ end
148
+ end
149
+
150
+ context "without credentials for given url" do
151
+ let(:creds_hash) { nil }
152
+
153
+ it "raises and error" do
154
+ expect { subject }.to raise_error /no credentials found/i
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
@@ -7,6 +7,7 @@ describe Bosh::Workspace::SpiffHelper do
7
7
  let(:path) { asset_dir("bin") }
8
8
  let(:templates) { ["foo.yml", "bar.yml"] }
9
9
  let(:target_file) { "spiffed_manifest.yml" }
10
+ let(:args) { [/spiff merge/, Hash] }
10
11
 
11
12
  around do |example|
12
13
  original_path = ENV["PATH"]
@@ -16,7 +17,7 @@ describe Bosh::Workspace::SpiffHelper do
16
17
  end
17
18
 
18
19
  before do
19
- expect(subject).to receive(:sh).and_yield(result)
20
+ expect(subject).to receive(:sh).with(*args).and_yield(result)
20
21
  end
21
22
 
22
23
  context "spiff not in path" do
@@ -40,16 +41,28 @@ describe Bosh::Workspace::SpiffHelper do
40
41
  end
41
42
  end
42
43
 
43
- describe ".merge" do
44
+ describe ".spiff_merge" do
44
45
  let(:file) { instance_double("File") }
45
46
  let(:output) { "---\n{}" }
46
47
  let(:result) { Bosh::Exec::Result.new("spiff", output, 0, false) }
47
48
 
48
- it "merges manifests" do
49
+ before do
49
50
  expect(File).to receive(:open).with(target_file, 'w').and_yield(file)
50
51
  expect(file).to receive(:write).with(output)
52
+ end
53
+
54
+ it "merges manifests" do
51
55
  subject.spiff_merge templates, target_file
52
56
  end
57
+
58
+ context "spaces in template paths" do
59
+ let(:templates) { ["space test/foo space test.yml"] }
60
+ let(:args) { [/space\\ test\/foo\\ space\\ test.yml/, Hash] }
61
+
62
+ it "merges manifests" do
63
+ subject.spiff_merge templates, target_file
64
+ end
65
+ end
53
66
  end
54
67
  end
55
68
  end
@@ -1,182 +1,71 @@
1
- describe Bosh::Workspace::ProjectDeployment do
2
- let(:project_deployment) { Bosh::Workspace::ProjectDeployment.new manifest_file }
3
- let(:manifest_file) { get_tmp_file_path(manifest.to_yaml, file_name) }
4
- let(:file_name) { "foo.yml" }
5
- let(:name) { "foo" }
6
- let(:uuid) { "e55134c3-0a63-47be-8409-c9e53e965d5c" }
7
- let(:domain_name) { "bosh" }
8
- let(:templates) { ["path_to_bar", "path_to_baz"] }
9
- let(:releases) do
10
- [{
11
- "name" => "foo",
12
- "version" => release_version,
13
- "ref" => release_ref,
14
- "git" => "example.com/foo.git"
15
- }]
16
- end
17
- let(:release_version) { 1 }
18
- let(:release_ref) { "eb8ccf" }
19
- let(:stemcells) { [
20
- { "name" => "bar", "version" => stemcell_version }
21
- ] }
22
- let(:stemcell_version) { 1 }
23
- let(:meta) { { "foo" => "bar" } }
24
- let(:manifest) { {
25
- "name" => name,
26
- "director_uuid" => uuid,
27
- "domain_name" => domain_name,
28
- "templates" => templates,
29
- "releases" => releases,
30
- "stemcells" => stemcells,
31
- "meta" => meta,
32
- } }
33
-
34
- subject { project_deployment }
35
-
36
- describe "#perform_validation" do
37
- subject { project_deployment.errors.first }
38
- let(:invalid_manifest) do
39
- if defined?(missing)
40
- manifest.delete_if { |key| Array(missing).include?(key) }
41
- else
42
- manifest
1
+ module Bosh::Workspace
2
+ describe ProjectDeployment do
3
+ subject { Bosh::Workspace::ProjectDeployment.new manifest_file }
4
+ let(:manifest_file) { get_tmp_file_path(manifest.to_yaml, file_name) }
5
+ let(:file_name) { "foo.yml" }
6
+ let(:manifest) { :manifest }
7
+
8
+ describe ".new" do
9
+ context "deployment file does not exist" do
10
+ before do
11
+ allow(File).to receive(:exist?).with(manifest_file).and_return(false)
12
+ end
13
+ it { expect { subject }.to raise_error(/deployment file.+not exist/i) }
43
14
  end
44
15
  end
45
- let(:manifest_file) { get_tmp_file_path(invalid_manifest.to_yaml) }
46
-
47
- before do
48
- project_deployment.validate
49
- expect(project_deployment).to_not be_valid
50
- end
51
16
 
52
- context "not a hash" do
53
- let(:invalid_manifest) { "foo" }
54
- it { should match(/Expected instance of Hash/) }
55
- end
56
-
57
- %w(name director_uuid releases templates meta stemcells).each do |field|
58
- context "missing #{field}" do
59
- let(:missing) { field }
60
- it { should match(/#{field}.*missing/i) }
17
+ describe "#perform_validation" do
18
+ context "valid" do
19
+ it "validates" do
20
+ allow_any_instance_of(Schemas::ProjectDeployment)
21
+ .to receive(:validate).with(manifest)
22
+ expect(subject).to be_valid
23
+ end
61
24
  end
62
- end
63
-
64
- context "optional domain_name" do
65
- let(:missing) { ["domain_name", "director_uuid"] }
66
- it { should match(/director_uuid/) }
67
- it { should_not match(/domain_name/) }
68
- end
69
25
 
70
- context "director_uuid" do
71
26
  context "invalid" do
72
- let(:uuid) { "invalid_uuid" }
73
- it { should match(/director_uuid.*doesn't validate/) }
74
- end
75
-
76
- context "current" do
77
- let(:uuid) { "current" }
78
- let(:missing) { "name" }
79
- it { should_not match(/director_uuid/) }
80
- it { should match(/name/) }
81
- end
82
- end
83
-
84
- context "releases" do
85
- let(:invalid_manifest) do
86
- manifest["releases"].map! { |r| r.delete_if { |key| Array(missing).include?(key) } }
87
- manifest
88
- end
89
-
90
- %w(name version git).each do |field_name|
91
- context "missing #{field_name}" do
92
- let(:missing) { field_name }
93
- it { should match(/#{field_name}.*missing/i) }
27
+ it "has errors" do
28
+ allow_any_instance_of(Schemas::ProjectDeployment)
29
+ .to receive(:validate).with(manifest)
30
+ .and_raise(Membrane::SchemaValidationError.new("foo"))
31
+ expect(subject).to_not be_valid
32
+ expect(subject.errors).to include "foo"
94
33
  end
95
34
  end
96
-
97
- context "latest version" do
98
- let(:missing) { "git" }
99
- let(:release_version) { "latest" }
100
- it { should match(/git.*missing/i) }
101
- it { should_not match(/version/i) }
102
- end
103
-
104
- context "invalid version" do
105
- let(:missing) { "git" }
106
- let(:release_version) { "foo" }
107
- it { should match(/git.*missing/i) }
108
- it { should match(/version.*doesn't validate/i) }
109
- end
110
-
111
- context "optional ref" do
112
- let(:missing) { ["git", "ref"] }
113
- it { should match(/git.*missing/i) }
114
- end
115
35
  end
116
36
 
117
- context "stemcells" do
118
- let(:invalid_manifest) do
119
- manifest["stemcells"].map! { |r| r.delete_if { |key| Array(missing).include?(key) } }
120
- manifest
121
- end
122
-
123
- %w(name version).each do |field_name|
124
- context "missing #{field_name}" do
125
- let(:missing) { field_name }
126
- it { should match(/#{field_name}.*missing/i) }
127
- end
128
- end
129
-
130
- context "latest version" do
131
- let(:missing) { "name" }
132
- let(:stemcell_version) { "latest" }
133
- it { should match(/name.*missing/i) }
134
- it { should_not match(/version/i) }
135
- end
37
+ describe "#director_uuid=" do
38
+ before { subject.director_uuid = "foo-bar" }
39
+ its(:director_uuid) { should eq "foo-bar" }
40
+ end
136
41
 
137
- context "patch version string" do
138
- let(:missing) { "name" }
139
- let(:stemcell_version) { "2719.1" }
140
- it { should match(/name.*missing/i) }
141
- it { should_not match(/version/i) }
42
+ describe "attr readers" do
43
+ let(:manifest) { {
44
+ "name" => :name,
45
+ "director_uuid" => :director_uuid,
46
+ "templates" => :templates,
47
+ "releases" => :releases,
48
+ "stemcells" => :stemcells,
49
+ "meta" => :meta,
50
+ "domain_name" => :domain_name,
51
+ } }
52
+
53
+ let(:director_uuid) { uuid }
54
+ %w(name director_uuid templates releases stemcells meta domain_name)
55
+ .each do |attr|
56
+ its(attr.to_sym) { should eq attr.to_sym }
142
57
  end
58
+ end
143
59
 
144
- context "patch version float" do
145
- let(:missing) { "name" }
146
- let(:stemcell_version) { 2719.1 }
147
- it { should match(/name.*missing/i) }
148
- it { should_not match(/version/i) }
60
+ describe "#merged_file" do
61
+ it "creates parent directory" do
62
+ dir = File.dirname(subject.merged_file)
63
+ expect(File.directory?(dir)).to be true
149
64
  end
150
65
 
151
- context "invalid version" do
152
- let(:missing) { "name" }
153
- let(:stemcell_version) { "foo" }
154
- it { should match(/name.*missing/i) }
155
- it { should match(/version.*should match/i) }
66
+ it "retruns merged file" do
67
+ expect(subject.merged_file).to match(/\.deployments\/#{file_name}/)
156
68
  end
157
69
  end
158
70
  end
159
-
160
- describe "#director_uuid=" do
161
- before { subject.director_uuid = "foo-bar" }
162
- its(:director_uuid) { should eq "foo-bar" }
163
- end
164
-
165
- describe "attr readers" do
166
- let(:director_uuid) { uuid }
167
- %w(name director_uuid templates releases stemcells meta).each do |attr|
168
- its(attr.to_sym) { should eq eval(attr) }
169
- end
170
- end
171
-
172
- describe "#merged_file" do
173
- it "creates parent directory" do
174
- dir = File.dirname(subject.merged_file)
175
- expect(File.directory?(dir)).to be true
176
- end
177
-
178
- it "retruns merged file" do
179
- expect(subject.merged_file).to match(/\.deployments\/#{file_name}/)
180
- end
181
- end
182
71
  end