knife-essentials 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  require 'chef_fs/file_system/base_fs_object'
2
- require 'chef_fs/file_system/not_found_exception'
2
+ require 'chef_fs/file_system/not_found_error'
3
3
  # TODO: these are needed for rest.get_rest() to work. This seems strange.
4
4
  require 'chef/role'
5
5
  require 'chef/node'
@@ -37,7 +37,7 @@ module ChefFS
37
37
  rest.delete_rest(api_path)
38
38
  rescue Net::HTTPServerException
39
39
  if $!.response.code == "404"
40
- raise ChefFS::FileSystem::NotFoundException, $!
40
+ raise ChefFS::FileSystem::NotFoundError.new($!), "#{path_for_printing} not found"
41
41
  else
42
42
  raise
43
43
  end
@@ -49,7 +49,7 @@ module ChefFS
49
49
  Chef::JSONCompat.to_json_pretty(rest.get_rest(api_path).to_hash)
50
50
  rescue Net::HTTPServerException
51
51
  if $!.response.code == "404"
52
- raise ChefFS::FileSystem::NotFoundException, $!
52
+ raise ChefFS::FileSystem::NotFoundError.new($!), "#{path_for_printing} not found"
53
53
  else
54
54
  raise
55
55
  end
@@ -1,5 +1,5 @@
1
1
  require 'chef_fs/file_system/chef_server_root_dir'
2
- require 'chef_fs/file_system/file_system_root_dir'
2
+ require 'chef_fs/file_system/chef_repository_file_system_root_dir'
3
3
  require 'chef_fs/file_pattern'
4
4
  require 'chef_fs/path_utils'
5
5
  require 'chef/config'
@@ -32,7 +32,7 @@ module ChefFS
32
32
  end
33
33
 
34
34
  def local_fs
35
- @local_fs ||= ChefFS::FileSystem::FileSystemRootDir.new(chef_repo)
35
+ @local_fs ||= ChefFS::FileSystem::ChefRepositoryFileSystemRootDir.new(chef_repo)
36
36
  end
37
37
 
38
38
  def pattern_args
@@ -1,4 +1,4 @@
1
1
  module ChefFS
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2"
3
3
  end
4
4
 
@@ -26,11 +26,13 @@ describe ChefFS::Diff do
26
26
  :both_dirs_empty => {},
27
27
  :dirs_empty_in_a_filled_in_b => {},
28
28
  :dirs_empty_in_b_filled_in_a => { :subsub => nil },
29
+ :dirs_in_a_cannot_be_in_b => {},
30
+ :file_in_a_cannot_be_in_b => nil,
29
31
  :a_only_dir => { :subsub => nil },
30
32
  :a_only_file => nil,
31
33
  :dir_in_a_file_in_b => {},
32
34
  :file_in_a_dir_in_b => nil
33
- })
35
+ }, /cannot_be_in_a/)
34
36
  }
35
37
  let(:b) {
36
38
  memory_fs('b', {
@@ -51,11 +53,13 @@ describe ChefFS::Diff do
51
53
  :both_dirs_empty => {},
52
54
  :dirs_empty_in_a_filled_in_b => { :subsub => nil },
53
55
  :dirs_empty_in_b_filled_in_a => {},
56
+ :dirs_in_b_cannot_be_in_a => {},
57
+ :file_in_b_cannot_be_in_a => nil,
54
58
  :b_only_dir => { :subsub => nil },
55
59
  :b_only_file => nil,
56
60
  :dir_in_a_file_in_b => nil,
57
61
  :file_in_a_dir_in_b => {}
58
- })
62
+ }, /cannot_be_in_b/)
59
63
  }
60
64
  it 'diffable_leaves' do
61
65
  diffable_leaves_should_yield_paths(a, b, nil,
@@ -75,6 +79,10 @@ describe ChefFS::Diff do
75
79
  /both_files_different
76
80
  /dirs_empty_in_b_filled_in_a/subsub
77
81
  /dirs_empty_in_a_filled_in_b/subsub
82
+ /dirs_in_a_cannot_be_in_b
83
+ /dirs_in_b_cannot_be_in_a
84
+ /file_in_a_cannot_be_in_b
85
+ /file_in_b_cannot_be_in_a
78
86
  /a_only_dir
79
87
  /a_only_file
80
88
  /b_only_dir
@@ -94,6 +102,8 @@ describe ChefFS::Diff do
94
102
  /both_dirs/sub_file_in_a_dir_in_b
95
103
  /both_files
96
104
  /both_files_different
105
+ /file_in_a_cannot_be_in_b
106
+ /file_in_b_cannot_be_in_a
97
107
  /a_only_file
98
108
  /b_only_file
99
109
  /dir_in_a_file_in_b
@@ -116,6 +126,8 @@ describe ChefFS::Diff do
116
126
  /both_dirs/sub_file_in_a_dir_in_b
117
127
  /dirs_empty_in_b_filled_in_a/subsub
118
128
  /dirs_empty_in_a_filled_in_b/subsub
129
+ /dirs_in_a_cannot_be_in_b
130
+ /dirs_in_b_cannot_be_in_a
119
131
  /a_only_dir
120
132
  /b_only_dir
121
133
  /dir_in_a_file_in_b
@@ -0,0 +1,212 @@
1
+ require 'chef_fs/file_system/chef_server_root_dir'
2
+
3
+ describe ChefFS::FileSystem::ChefServerRootDir do
4
+ shared_examples 'a json endpoint dir leaf' do
5
+ it 'parent is endpoint' do
6
+ endpoint_leaf.parent.should == endpoint
7
+ end
8
+ it 'name is correct' do
9
+ endpoint_leaf.name.should == "#{endpoint_leaf_name}.json"
10
+ end
11
+ it 'path is correct' do
12
+ endpoint_leaf.path.should == "/#{endpoint_name}/#{endpoint_leaf_name}.json"
13
+ end
14
+ it 'path_for_printing is correct' do
15
+ endpoint_leaf.path_for_printing.should == "remote/#{endpoint_name}/#{endpoint_leaf_name}.json"
16
+ end
17
+ it 'is not a directory' do
18
+ endpoint_leaf.dir?.should be_false
19
+ end
20
+ it 'exists' do
21
+ should_receive_children
22
+ endpoint_leaf.exists?.should be_true
23
+ end
24
+ it 'read returns content' do
25
+ @rest.should_receive(:get_rest).with("#{endpoint_name}/#{endpoint_leaf_name}/environments/env").once.and_return(
26
+ {
27
+ 'a' => 'b'
28
+ })
29
+ endpoint_leaf.read.should == '{
30
+ "a": "b"
31
+ }'
32
+ end
33
+ end
34
+
35
+ shared_examples 'a json rest endpoint dir' do
36
+ it 'parent is root' do
37
+ endpoint.parent.should == root_dir
38
+ end
39
+ it 'has correct name' do
40
+ endpoint.name.should == endpoint_name
41
+ end
42
+ it 'has correct path' do
43
+ endpoint.path.should == "/#{endpoint_name}"
44
+ end
45
+ it 'has correct path_for_printing' do
46
+ endpoint.path_for_printing.should == "remote/#{endpoint_name}"
47
+ end
48
+ it 'is a directory' do
49
+ endpoint.dir?.should be_true
50
+ end
51
+ it 'exists' do
52
+ endpoint.exists?.should be_true
53
+ end
54
+ it 'can have json files as children' do
55
+ endpoint.can_have_child?('blah.json', false).should be_true
56
+ end
57
+ it 'cannot have non-json files as children' do
58
+ endpoint.can_have_child?('blah', false).should be_false
59
+ end
60
+ it 'cannot have directories as children' do
61
+ endpoint.can_have_child?('blah', true).should be_false
62
+ endpoint.can_have_child?('blah.json', true).should be_false
63
+ end
64
+ let(:should_receive_children) {
65
+ @rest.should_receive(:get_rest).with(endpoint_name).once.and_return(
66
+ {
67
+ "achild" => "http://opscode.com/achild",
68
+ "bchild" => "http://opscode.com/bchild"
69
+ })
70
+ }
71
+ it 'has correct children' do
72
+ should_receive_children
73
+ endpoint.children.map { |child| child.name }.should =~ %w(achild.json bchild.json)
74
+ end
75
+ context 'achild in endpoint.children' do
76
+ let(:endpoint_leaf_name) { 'achild' }
77
+ let(:endpoint_leaf) do
78
+ should_receive_children
79
+ endpoint.children.select { |child| child.name == 'achild.json' }.first
80
+ end
81
+ it_behaves_like 'a json endpoint dir leaf'
82
+ end
83
+ context 'endpoint.child(achild)' do
84
+ let(:endpoint_leaf_name) { 'achild' }
85
+ let(:endpoint_leaf) { endpoint.child('achild.json') }
86
+ it_behaves_like 'a json endpoint dir leaf'
87
+ end
88
+ context 'nonexistent child()' do
89
+ let(:nonexistent_child) { endpoint.child('blah.json') }
90
+ it 'has correct parent, name, path and path_for_printing' do
91
+ nonexistent_child.parent.should == endpoint
92
+ nonexistent_child.name.should == "blah.json"
93
+ nonexistent_child.path.should == "#{endpoint.path}/blah.json"
94
+ nonexistent_child.path_for_printing.should == "#{endpoint.path_for_printing}/blah.json"
95
+ end
96
+ it 'does not exist' do
97
+ should_receive_children
98
+ nonexistent_child.exists?.should be_false
99
+ end
100
+ it 'is not a directory' do
101
+ nonexistent_child.dir?.should be_false
102
+ end
103
+ it 'read returns NotFoundError' do
104
+ @rest.should_receive(:get_rest).with("#{endpoint_name}/blah/environments/env").once.and_raise(Net::HTTPServerException.new(nil,Net::HTTPResponse.new(nil,'404',nil)))
105
+ expect { nonexistent_child.read }.to raise_error(ChefFS::FileSystem::NotFoundError)
106
+ end
107
+ end
108
+ end
109
+
110
+ let(:root_dir) {
111
+ ChefFS::FileSystem::ChefServerRootDir.new('remote',
112
+ {
113
+ :chef_server_url => 'url',
114
+ :node_name => 'username',
115
+ :client_key => 'key',
116
+ :environment => 'env'
117
+ })
118
+ }
119
+ before(:each) do
120
+ @rest = double("rest")
121
+ Chef::REST.stub(:new).with('url','username','key') { @rest }
122
+ end
123
+ context 'the root directory' do
124
+ it 'has no parent' do
125
+ root_dir.parent.should == nil
126
+ end
127
+ it 'is a directory' do
128
+ root_dir.dir?.should be_true
129
+ end
130
+ it 'exists' do
131
+ root_dir.exists?.should be_true
132
+ end
133
+ it 'has name ""' do
134
+ root_dir.name.should == ""
135
+ end
136
+ it 'has path /' do
137
+ root_dir.path.should == '/'
138
+ end
139
+ it 'has path_for_printing remote/' do
140
+ root_dir.path_for_printing.should == 'remote/'
141
+ end
142
+ it 'has correct children' do
143
+ root_dir.children.map { |child| child.name }.should =~ %w(clients cookbooks data_bags environments nodes roles)
144
+ end
145
+ it 'can have children with the known names' do
146
+ %w(clients cookbooks data_bags environments nodes roles).each { |child| root_dir.can_have_child?(child, true).should be_true }
147
+ end
148
+ it 'cannot have files as children' do
149
+ %w(clients cookbooks data_bags environments nodes roles).each { |child| root_dir.can_have_child?(child, false).should be_false }
150
+ root_dir.can_have_child?('blah', false).should be_false
151
+ end
152
+ it 'cannot have other child directories than the known names' do
153
+ root_dir.can_have_child?('blah', true).should be_false
154
+ end
155
+ it 'child() responds to children' do
156
+ %w(clients cookbooks data_bags environments nodes roles).each { |child| root_dir.child(child).exists?.should be_true }
157
+ end
158
+ context 'nonexistent child()' do
159
+ let(:nonexistent_child) { root_dir.child('blah') }
160
+ it 'has correct parent, name, path and path_for_printing' do
161
+ nonexistent_child.parent.should == root_dir
162
+ nonexistent_child.name.should == "blah"
163
+ nonexistent_child.path.should == "/blah"
164
+ nonexistent_child.path_for_printing.should == "remote/blah"
165
+ end
166
+ it 'does not exist' do
167
+ nonexistent_child.exists?.should be_false
168
+ end
169
+ it 'is not a directory' do
170
+ nonexistent_child.dir?.should be_false
171
+ end
172
+ it 'read returns NotFoundError' do
173
+ expect { nonexistent_child.read }.to raise_error(ChefFS::FileSystem::NotFoundError)
174
+ end
175
+ end
176
+ end
177
+
178
+ context 'clients in children' do
179
+ let(:endpoint_name) { 'clients' }
180
+ let(:endpoint) { root_dir.children.select { |child| child.name == 'clients' }.first }
181
+
182
+ it_behaves_like 'a json rest endpoint dir'
183
+ end
184
+
185
+ context 'root.child(clients)' do
186
+ let(:endpoint_name) { 'clients' }
187
+ let(:endpoint) { root_dir.child('clients') }
188
+
189
+ it_behaves_like 'a json rest endpoint dir'
190
+ end
191
+
192
+ context 'root.child(environments)' do
193
+ let(:endpoint_name) { 'environments' }
194
+ let(:endpoint) { root_dir.child('environments') }
195
+
196
+ it_behaves_like 'a json rest endpoint dir'
197
+ end
198
+
199
+ context 'root.child(nodes)' do
200
+ let(:endpoint_name) { 'nodes' }
201
+ let(:endpoint) { root_dir.child('nodes') }
202
+
203
+ it_behaves_like 'a json rest endpoint dir'
204
+ end
205
+
206
+ context 'root.child(roles)' do
207
+ let(:endpoint_name) { 'roles' }
208
+ let(:endpoint) { root_dir.child('roles') }
209
+
210
+ it_behaves_like 'a json rest endpoint dir'
211
+ end
212
+ end
@@ -0,0 +1,549 @@
1
+ require 'chef_fs/file_system/chef_server_root_dir'
2
+ require 'chef_fs/file_system'
3
+
4
+ describe ChefFS::FileSystem::CookbooksDir do
5
+ let(:root_dir) {
6
+ ChefFS::FileSystem::ChefServerRootDir.new('remote',
7
+ {
8
+ :chef_server_url => 'url',
9
+ :node_name => 'username',
10
+ :client_key => 'key',
11
+ :environment => 'env'
12
+ })
13
+ }
14
+ let(:cookbooks_dir) { root_dir.child('cookbooks') }
15
+ let(:should_list_cookbooks) do
16
+ @rest.should_receive(:get_rest).with('cookbooks').once.and_return(
17
+ {
18
+ "achild" => "http://opscode.com/achild",
19
+ "bchild" => "http://opscode.com/bchild"
20
+ })
21
+ end
22
+ before(:each) do
23
+ @rest = double("rest")
24
+ Chef::REST.stub(:new).with('url','username','key') { @rest }
25
+ end
26
+
27
+ it 'has / as parent' do
28
+ cookbooks_dir.parent.should == root_dir
29
+ end
30
+ it 'is a directory' do
31
+ cookbooks_dir.dir?.should be_true
32
+ end
33
+ it 'exists' do
34
+ cookbooks_dir.exists?.should be_true
35
+ end
36
+ it 'has name cookbooks' do
37
+ cookbooks_dir.name.should == 'cookbooks'
38
+ end
39
+ it 'has path /cookbooks' do
40
+ cookbooks_dir.path.should == '/cookbooks'
41
+ end
42
+ it 'has path_for_printing remote/cookbooks' do
43
+ cookbooks_dir.path_for_printing.should == 'remote/cookbooks'
44
+ end
45
+ it 'has correct children' do
46
+ should_list_cookbooks
47
+ cookbooks_dir.children.map { |child| child.name }.should =~ %w(achild bchild)
48
+ end
49
+ it 'can have directories as children' do
50
+ cookbooks_dir.can_have_child?('blah', true).should be_true
51
+ end
52
+ it 'cannot have files as children' do
53
+ cookbooks_dir.can_have_child?('blah', false).should be_false
54
+ end
55
+
56
+ #
57
+ # Cookbook dir (/cookbooks/<blah>)
58
+ #
59
+ shared_examples_for 'a segment directory' do
60
+ it 'has cookbook as parent' do
61
+ segment_dir.parent.should == cookbook_dir
62
+ end
63
+ it 'exists' do
64
+ segment_dir.exists?.should be_true
65
+ end
66
+ it 'is a directory' do
67
+ segment_dir.dir?.should be_true
68
+ end
69
+ it 'name is correct' do
70
+ segment_dir.name.should == segment_dir_name
71
+ end
72
+ it 'path is correct' do
73
+ segment_dir.path.should == "/cookbooks/#{cookbook_dir_name}/#{segment_dir_name}"
74
+ end
75
+ it 'path_for_printing is correct' do
76
+ segment_dir.path_for_printing.should == "remote/cookbooks/#{cookbook_dir_name}/#{segment_dir_name}"
77
+ end
78
+ it 'has the right children' do
79
+ segment_dir.children =~ %w(a.rb b.txt subdir)
80
+ end
81
+ it 'children are identical to child()' do
82
+ segment_dir.child('a.rb').should == segment_dir.children.select { |child| child.name == 'a.rb' }.first
83
+ segment_dir.child('b.txt').should == segment_dir.children.select { |child| child.name == 'b.txt' }.first
84
+ segment_dir.child('subdir').should == segment_dir.children.select { |child| child.name == 'subdir' }.first
85
+ end
86
+ context 'subdirectory' do
87
+ it 'has segment as a parent' do
88
+ segment_dir.child('subdir').parent.should == segment_dir
89
+ end
90
+ it 'exists' do
91
+ segment_dir.child('subdir').exists?.should be_true
92
+ end
93
+ it 'is a directory' do
94
+ segment_dir.child('subdir').dir?.should be_true
95
+ end
96
+ it 'name is subdir' do
97
+ segment_dir.child('subdir').name.should == 'subdir'
98
+ end
99
+ it 'path is correct' do
100
+ segment_dir.child('subdir').path.should == "/cookbooks/#{cookbook_dir_name}/#{segment_dir_name}/subdir"
101
+ end
102
+ it 'path_for_printing is correct' do
103
+ segment_dir.child('subdir').path_for_printing.should == "remote/cookbooks/#{cookbook_dir_name}/#{segment_dir_name}/subdir"
104
+ end
105
+ it 'has the right children' do
106
+ segment_dir.child('subdir').children =~ %w(a.rb b.txt)
107
+ end
108
+ it 'children are identical to child()' do
109
+ segment_dir.child('subdir').child('a.rb').should == segment_dir.child('subdir').children.select { |child| child.name == 'a.rb' }.first
110
+ segment_dir.child('subdir').child('b.txt').should == segment_dir.child('subdir').children.select { |child| child.name == 'b.txt' }.first
111
+ end
112
+ end
113
+ end
114
+
115
+ shared_examples_for 'a cookbook' do
116
+ it 'has cookbooks as parent' do
117
+ cookbook_dir.parent == cookbooks_dir
118
+ end
119
+ it 'is a directory' do
120
+ should_list_cookbooks
121
+ cookbook_dir.dir?.should be_true
122
+ end
123
+ it 'exists' do
124
+ should_list_cookbooks
125
+ cookbook_dir.exists?.should be_true
126
+ end
127
+ it 'has name <cookbook name>' do
128
+ cookbook_dir.name.should == cookbook_dir_name
129
+ end
130
+ it 'has path /cookbooks/<cookbook name>' do
131
+ cookbook_dir.path.should == "/cookbooks/#{cookbook_dir_name}"
132
+ end
133
+ it 'has path_for_printing remote/cookbooks/<cookbook name>' do
134
+ cookbook_dir.path_for_printing.should == "remote/cookbooks/#{cookbook_dir_name}"
135
+ end
136
+ it 'can have segment directories as children' do
137
+ cookbook_dir.can_have_child?('attributes', true).should be_true
138
+ cookbook_dir.can_have_child?('definitions', true).should be_true
139
+ cookbook_dir.can_have_child?('recipes', true).should be_true
140
+ cookbook_dir.can_have_child?('libraries', true).should be_true
141
+ cookbook_dir.can_have_child?('templates', true).should be_true
142
+ cookbook_dir.can_have_child?('files', true).should be_true
143
+ cookbook_dir.can_have_child?('resources', true).should be_true
144
+ cookbook_dir.can_have_child?('providers', true).should be_true
145
+ end
146
+ it 'cannot have arbitrary directories as children' do
147
+ cookbook_dir.can_have_child?('blah', true).should be_false
148
+ cookbook_dir.can_have_child?('root_files', true).should be_false
149
+ end
150
+ it 'can have files as children' do
151
+ cookbook_dir.can_have_child?('blah', false).should be_true
152
+ cookbook_dir.can_have_child?('root_files', false).should be_true
153
+ cookbook_dir.can_have_child?('attributes', false).should be_true
154
+ cookbook_dir.can_have_child?('definitions', false).should be_true
155
+ cookbook_dir.can_have_child?('recipes', false).should be_true
156
+ cookbook_dir.can_have_child?('libraries', false).should be_true
157
+ cookbook_dir.can_have_child?('templates', false).should be_true
158
+ cookbook_dir.can_have_child?('files', false).should be_true
159
+ cookbook_dir.can_have_child?('resources', false).should be_true
160
+ cookbook_dir.can_have_child?('providers', false).should be_true
161
+ end
162
+ # TODO test empty parts, cross-contamination (root_files named templates/x.txt, libraries named recipes/blah.txt)
163
+ context 'with a full directory structure' do
164
+ def json_file(path, checksum)
165
+ filename = ChefFS::PathUtils.split(path)[-1]
166
+ {
167
+ :name => filename,
168
+ :url => "cookbook_file:#{path}",
169
+ :checksum => checksum,
170
+ :path => path,
171
+ :specificity => "default"
172
+ }
173
+ end
174
+ def json_files(cookbook_dir)
175
+ result = []
176
+ files.each do |filename|
177
+ if filename =~ /^#{cookbook_dir}\//
178
+ result << json_file(filename, file_checksums[filename])
179
+ end
180
+ end
181
+ result
182
+ end
183
+ let(:files) {
184
+ result = []
185
+ %w(attributes definitions files libraries providers recipes resources templates).each do |segment|
186
+ result << "#{segment}/a.rb"
187
+ result << "#{segment}/b.txt"
188
+ result << "#{segment}/subdir/a.rb"
189
+ result << "#{segment}/subdir/b.txt"
190
+ end
191
+ result << 'a.rb'
192
+ result << 'b.txt'
193
+ result << 'subdir/a.rb'
194
+ result << 'subdir/b.txt'
195
+ result << 'root_files'
196
+ result
197
+ }
198
+ let(:file_checksums) {
199
+ result = {}
200
+ files.each_with_index do |file, i|
201
+ result[file] = i.to_s(16)
202
+ end
203
+ result
204
+ }
205
+ let(:should_get_cookbook) do
206
+ cookbook = double('cookbook')
207
+ cookbook.should_receive(:manifest).and_return({
208
+ :attributes => json_files('attributes'),
209
+ :definitions => json_files('definitions'),
210
+ :files => json_files('files'),
211
+ :libraries => json_files('libraries'),
212
+ :providers => json_files('providers'),
213
+ :recipes => json_files('recipes'),
214
+ :resources => json_files('resources'),
215
+ :templates => json_files('templates'),
216
+ :root_files => [
217
+ json_file('a.rb', file_checksums['a.rb']),
218
+ json_file('b.txt', file_checksums['b.txt']),
219
+ json_file('subdir/a.rb', file_checksums['subdir/a.rb']),
220
+ json_file('subdir/b.txt', file_checksums['subdir/b.txt']),
221
+ json_file('root_files', file_checksums['root_files'])
222
+ ]
223
+ })
224
+ @rest.should_receive(:get_rest).with("cookbooks/#{cookbook_dir_name}/_latest").once.and_return(cookbook)
225
+ end
226
+
227
+ it 'has correct children' do
228
+ should_get_cookbook
229
+ cookbook_dir.children.map { |child| child.name }.should =~ %w(attributes definitions files libraries providers recipes resources templates a.rb b.txt subdir root_files)
230
+ end
231
+ it 'children and child() yield the exact same objects' do
232
+ should_get_cookbook
233
+ cookbook_dir.children.each { |child| child.should == cookbook_dir.child(child.name) }
234
+ end
235
+ it 'all files exist (recursive) and have correct parent, path, path_for_printing, checksum and type' do
236
+ should_get_cookbook
237
+ file_checksums.each do |path, checksum|
238
+ file = ChefFS::FileSystem.resolve_path(cookbook_dir, path)
239
+ file_parts = path.split('/')
240
+ if file_parts.length == 3
241
+ file.parent.parent.parent.should == cookbook_dir
242
+ elsif file_parts.length == 2
243
+ file.parent.parent.should == cookbook_dir
244
+ else
245
+ file.parent.should == cookbook_dir
246
+ end
247
+ file.exists?.should be_true
248
+ file.dir?.should be_false
249
+ file.name.should == file_parts[-1]
250
+ file.path.should == "/cookbooks/#{cookbook_dir_name}/#{path}"
251
+ file.path_for_printing.should == "remote/cookbooks/#{cookbook_dir_name}/#{path}"
252
+ file.checksum.should == checksum
253
+ end
254
+ end
255
+ it 'all files can be read' do
256
+ should_get_cookbook
257
+ files.each do |path|
258
+ @rest.should_receive(:get_rest).with("cookbook_file:#{path}").once.and_return("This is #{path}'s content")
259
+ @rest.should_receive(:sign_on_redirect).with(no_args()).once.and_return(true)
260
+ @rest.should_receive(:sign_on_redirect=).with(false).once
261
+ @rest.should_receive(:sign_on_redirect=).with(true).once
262
+ file = ChefFS::FileSystem.resolve_path(cookbook_dir, path)
263
+ file.read.should == "This is #{path}'s content"
264
+ end
265
+ end
266
+
267
+ context 'the attributes segment' do
268
+ let(:segment_dir) { cookbook_dir.child('attributes') }
269
+ let(:segment_dir_name) { 'attributes' }
270
+ it_behaves_like 'a segment directory'
271
+
272
+ before(:each) do
273
+ should_get_cookbook
274
+ end
275
+
276
+ it 'can have ruby files' do
277
+ should_get_cookbook
278
+ segment_dir.can_have_child?('blah.rb', false).should be_true
279
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
280
+ end
281
+ it 'cannot have non-ruby files' do
282
+ should_get_cookbook
283
+ segment_dir.can_have_child?('blah.txt', false).should be_false
284
+ segment_dir.can_have_child?('.blah.txt', false).should be_false
285
+ end
286
+ it 'cannot have subdirectories' do
287
+ should_get_cookbook
288
+ segment_dir.can_have_child?('blah', true).should be_false
289
+ end
290
+ end
291
+
292
+ context 'the definitions segment' do
293
+ let(:segment_dir) { cookbook_dir.child('definitions') }
294
+ let(:segment_dir_name) { 'definitions' }
295
+ it_behaves_like 'a segment directory'
296
+
297
+ before(:each) do
298
+ should_get_cookbook
299
+ end
300
+
301
+ it 'can have ruby files' do
302
+ segment_dir.can_have_child?('blah.rb', false).should be_true
303
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
304
+ end
305
+ it 'cannot have non-ruby files' do
306
+ segment_dir.can_have_child?('blah.txt', false).should be_false
307
+ segment_dir.can_have_child?('.blah.txt', false).should be_false
308
+ end
309
+ it 'cannot have subdirectories' do
310
+ segment_dir.can_have_child?('blah', true).should be_false
311
+ end
312
+ end
313
+
314
+ context 'the files segment' do
315
+ let(:segment_dir) { cookbook_dir.child('files') }
316
+ let(:segment_dir_name) { 'files' }
317
+ it_behaves_like 'a segment directory'
318
+
319
+ before(:each) do
320
+ should_get_cookbook
321
+ end
322
+
323
+ it 'can have ruby files' do
324
+ segment_dir.can_have_child?('blah.rb', false).should be_true
325
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
326
+ end
327
+ it 'can have non-ruby files' do
328
+ segment_dir.can_have_child?('blah.txt', false).should be_true
329
+ segment_dir.can_have_child?('.blah.txt', false).should be_true
330
+ end
331
+ it 'can have subdirectories' do
332
+ segment_dir.can_have_child?('blah', true).should be_true
333
+ end
334
+ it 'subdirectories can have ruby files' do
335
+ segment_dir.child('subdir').can_have_child?('blah.rb', false).should be_true
336
+ segment_dir.child('subdir').can_have_child?('.blah.rb', false).should be_true
337
+ end
338
+ it 'subdirectories can have non-ruby files' do
339
+ segment_dir.child('subdir').can_have_child?('blah.txt', false).should be_true
340
+ segment_dir.child('subdir').can_have_child?('.blah.txt', false).should be_true
341
+ end
342
+ it 'subdirectories can have subdirectories' do
343
+ segment_dir.child('subdir').can_have_child?('blah', true).should be_true
344
+ end
345
+ end
346
+
347
+ context 'the libraries segment' do
348
+ let(:segment_dir) { cookbook_dir.child('libraries') }
349
+ let(:segment_dir_name) { 'libraries' }
350
+ it_behaves_like 'a segment directory'
351
+
352
+ before(:each) do
353
+ should_get_cookbook
354
+ end
355
+
356
+ it 'can have ruby files' do
357
+ segment_dir.can_have_child?('blah.rb', false).should be_true
358
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
359
+ end
360
+ it 'cannot have non-ruby files' do
361
+ segment_dir.can_have_child?('blah.txt', false).should be_false
362
+ segment_dir.can_have_child?('.blah.txt', false).should be_false
363
+ end
364
+ it 'cannot have subdirectories' do
365
+ segment_dir.can_have_child?('blah', true).should be_false
366
+ end
367
+ end
368
+
369
+ context 'the providers segment' do
370
+ let(:segment_dir) { cookbook_dir.child('providers') }
371
+ let(:segment_dir_name) { 'providers' }
372
+ it_behaves_like 'a segment directory'
373
+
374
+ before(:each) do
375
+ should_get_cookbook
376
+ end
377
+
378
+ it 'can have ruby files' do
379
+ segment_dir.can_have_child?('blah.rb', false).should be_true
380
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
381
+ end
382
+ it 'cannot have non-ruby files' do
383
+ segment_dir.can_have_child?('blah.txt', false).should be_false
384
+ segment_dir.can_have_child?('.blah.txt', false).should be_false
385
+ end
386
+ it 'can have subdirectories' do
387
+ segment_dir.can_have_child?('blah', true).should be_true
388
+ end
389
+ it 'subdirectories can have ruby files' do
390
+ segment_dir.child('subdir').can_have_child?('blah.rb', false).should be_true
391
+ segment_dir.child('subdir').can_have_child?('.blah.rb', false).should be_true
392
+ end
393
+ it 'subdirectories cannot have non-ruby files' do
394
+ segment_dir.child('subdir').can_have_child?('blah.txt', false).should be_false
395
+ segment_dir.child('subdir').can_have_child?('.blah.txt', false).should be_false
396
+ end
397
+ it 'subdirectories can have subdirectories' do
398
+ segment_dir.child('subdir').can_have_child?('blah', true).should be_true
399
+ end
400
+ end
401
+
402
+ context 'the recipes segment' do
403
+ let(:segment_dir) { cookbook_dir.child('recipes') }
404
+ let(:segment_dir_name) { 'recipes' }
405
+ it_behaves_like 'a segment directory'
406
+
407
+ before(:each) do
408
+ should_get_cookbook
409
+ end
410
+
411
+ it 'can have ruby files' do
412
+ segment_dir.can_have_child?('blah.rb', false).should be_true
413
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
414
+ end
415
+ it 'cannot have non-ruby files' do
416
+ segment_dir.can_have_child?('blah.txt', false).should be_false
417
+ segment_dir.can_have_child?('.blah.txt', false).should be_false
418
+ end
419
+ it 'cannot have subdirectories' do
420
+ segment_dir.can_have_child?('blah', true).should be_false
421
+ end
422
+ end
423
+
424
+ context 'the resources segment' do
425
+ let(:segment_dir) { cookbook_dir.child('resources') }
426
+ let(:segment_dir_name) { 'resources' }
427
+ it_behaves_like 'a segment directory'
428
+
429
+ before(:each) do
430
+ should_get_cookbook
431
+ end
432
+
433
+ it 'can have ruby files' do
434
+ segment_dir.can_have_child?('blah.rb', false).should be_true
435
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
436
+ end
437
+ it 'cannot have non-ruby files' do
438
+ segment_dir.can_have_child?('blah.txt', false).should be_false
439
+ segment_dir.can_have_child?('.blah.txt', false).should be_false
440
+ end
441
+ it 'can have subdirectories' do
442
+ segment_dir.can_have_child?('blah', true).should be_true
443
+ end
444
+ it 'subdirectories can have ruby files' do
445
+ segment_dir.child('subdir').can_have_child?('blah.rb', false).should be_true
446
+ segment_dir.child('subdir').can_have_child?('.blah.rb', false).should be_true
447
+ end
448
+ it 'subdirectories cannot have non-ruby files' do
449
+ segment_dir.child('subdir').can_have_child?('blah.txt', false).should be_false
450
+ segment_dir.child('subdir').can_have_child?('.blah.txt', false).should be_false
451
+ end
452
+ it 'subdirectories can have subdirectories' do
453
+ segment_dir.child('subdir').can_have_child?('blah', true).should be_true
454
+ end
455
+ end
456
+
457
+ context 'the templates segment' do
458
+ let(:segment_dir) { cookbook_dir.child('templates') }
459
+ let(:segment_dir_name) { 'templates' }
460
+ it_behaves_like 'a segment directory'
461
+
462
+ before(:each) do
463
+ should_get_cookbook
464
+ end
465
+
466
+ it 'can have ruby files' do
467
+ segment_dir.can_have_child?('blah.rb', false).should be_true
468
+ segment_dir.can_have_child?('.blah.rb', false).should be_true
469
+ end
470
+ it 'can have non-ruby files' do
471
+ segment_dir.can_have_child?('blah.txt', false).should be_true
472
+ segment_dir.can_have_child?('.blah.txt', false).should be_true
473
+ end
474
+ it 'can have subdirectories' do
475
+ segment_dir.can_have_child?('blah', true).should be_true
476
+ end
477
+ it 'subdirectories can have ruby files' do
478
+ segment_dir.child('subdir').can_have_child?('blah.rb', false).should be_true
479
+ segment_dir.child('subdir').can_have_child?('.blah.rb', false).should be_true
480
+ end
481
+ it 'subdirectories can have non-ruby files' do
482
+ segment_dir.child('subdir').can_have_child?('blah.txt', false).should be_true
483
+ segment_dir.child('subdir').can_have_child?('.blah.txt', false).should be_true
484
+ end
485
+ it 'subdirectories can have subdirectories' do
486
+ segment_dir.child('subdir').can_have_child?('blah', true).should be_true
487
+ end
488
+ end
489
+
490
+ context 'root subdirectories' do
491
+ let(:root_subdir) { cookbook_dir.child('subdir') }
492
+
493
+ before(:each) do
494
+ should_get_cookbook
495
+ end
496
+
497
+ # Really, since these shouldn't exist in the first place,
498
+ # it doesn't matter; but these REALLY shouldn't be able to
499
+ # have any files in them at all.
500
+ it 'can have ruby files' do
501
+ root_subdir.can_have_child?('blah.rb', false).should be_true
502
+ root_subdir.can_have_child?('.blah.rb', false).should be_true
503
+ end
504
+ it 'can have non-ruby files' do
505
+ root_subdir.can_have_child?('blah.txt', false).should be_true
506
+ root_subdir.can_have_child?('.blah.txt', false).should be_true
507
+ end
508
+ it 'cannot have subdirectories' do
509
+ root_subdir.can_have_child?('blah', true).should be_false
510
+ end
511
+ end
512
+ end
513
+ end
514
+
515
+ context 'achild from cookbooks_dir.children' do
516
+ let(:cookbook_dir_name) { 'achild' }
517
+ let(:cookbook_dir) do
518
+ should_list_cookbooks
519
+ cookbooks_dir.children.select { |child| child.name == 'achild' }.first
520
+ end
521
+ it_behaves_like 'a cookbook'
522
+ end
523
+ context 'cookbooks_dir.child(achild)' do
524
+ let(:cookbook_dir_name) { 'achild' }
525
+ let(:cookbook_dir) { cookbooks_dir.child('achild') }
526
+ it_behaves_like 'a cookbook'
527
+ end
528
+ context 'nonexistent cookbooks_dir.child()' do
529
+ let(:nonexistent_child) { cookbooks_dir.child('blah') }
530
+ it 'has correct parent, name, path and path_for_printing' do
531
+ nonexistent_child.parent.should == cookbooks_dir
532
+ nonexistent_child.name.should == "blah"
533
+ nonexistent_child.path.should == "/cookbooks/blah"
534
+ nonexistent_child.path_for_printing.should == "remote/cookbooks/blah"
535
+ end
536
+ it 'does not exist' do
537
+ should_list_cookbooks
538
+ nonexistent_child.exists?.should be_false
539
+ end
540
+ it 'is a directory' do
541
+ should_list_cookbooks
542
+ nonexistent_child.dir?.should be_false
543
+ end
544
+ it 'read returns NotFoundError' do
545
+ expect { nonexistent_child.read }.to raise_error(ChefFS::FileSystem::NotFoundError)
546
+ end
547
+ end
548
+
549
+ end