buildpack-support 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,13 +29,15 @@ module BuildpackSupport
29
29
  #
30
30
  # @param [Pathname] cache_root the filesystem root for the file created and expected by this class
31
31
  # @param [String] uri a uri which uniquely identifies the file in the cache
32
- def initialize(cache_root, uri)
33
- FileUtils.mkdir_p cache_root
34
-
35
- key = URI.escape(uri, '/')
32
+ # @param [Boolean] mutable whether the cached file should be mutable
33
+ def initialize(cache_root, uri, mutable)
34
+ key = URI.escape(uri, ':/')
36
35
  @cached = cache_root + "#{key}.cached"
37
36
  @etag = cache_root + "#{key}.etag"
38
37
  @last_modified = cache_root + "#{key}.last_modified"
38
+ @mutable = mutable
39
+
40
+ FileUtils.mkdir_p cache_root if mutable
39
41
  end
40
42
 
41
43
  # Opens the cached file
@@ -58,7 +60,7 @@ module BuildpackSupport
58
60
 
59
61
  # Destroys the cached file
60
62
  def destroy
61
- [@cached, @etag, @last_modified].each { |f| f.delete if f.exist? }
63
+ [@cached, @etag, @last_modified].each { |f| f.delete if f.exist? } if @mutable
62
64
  end
63
65
 
64
66
  # Opens the etag file
@@ -66,7 +66,7 @@ module BuildpackSupport
66
66
  cached_file, downloaded = from_immutable_caches(uri), false unless cached_file
67
67
 
68
68
  fail "Unable to find cached file for #{uri}" unless cached_file
69
- cached_file.cached(File::RDONLY, downloaded, &block)
69
+ cached_file.cached(File::RDONLY | File::BINARY, downloaded, &block)
70
70
  end
71
71
 
72
72
  # Removes an item from the mutable cache.
@@ -74,7 +74,7 @@ module BuildpackSupport
74
74
  # @param [String] uri the URI of the item
75
75
  # @return [Void]
76
76
  def evict(uri)
77
- CachedFile.new(@mutable_cache_root, uri).destroy
77
+ CachedFile.new(@mutable_cache_root, uri, true).destroy
78
78
  end
79
79
 
80
80
  private
@@ -138,7 +138,7 @@ module BuildpackSupport
138
138
  end
139
139
 
140
140
  def cache_content(response, cached_file)
141
- cached_file.cached(File::CREAT | File::WRONLY) do |f|
141
+ cached_file.cached(File::CREAT | File::WRONLY | File::BINARY) do |f|
142
142
  @logger.debug { "Persisting content to #{f.path}" }
143
143
 
144
144
  f.truncate(0)
@@ -156,7 +156,7 @@ module BuildpackSupport
156
156
 
157
157
  @logger.debug { "Persisting etag: #{etag}" }
158
158
 
159
- cached_file.etag(File::CREAT | File::WRONLY) do |f|
159
+ cached_file.etag(File::CREAT | File::WRONLY | File::BINARY) do |f|
160
160
  f.truncate(0)
161
161
  f.write etag
162
162
  f.fsync
@@ -170,7 +170,7 @@ module BuildpackSupport
170
170
 
171
171
  @logger.debug { "Persisting last-modified: #{last_modified}" }
172
172
 
173
- cached_file.last_modified(File::CREAT | File::WRONLY) do |f|
173
+ cached_file.last_modified(File::CREAT | File::WRONLY | File::BINARY) do |f|
174
174
  f.truncate(0)
175
175
  f.write last_modified
176
176
  f.fsync
@@ -178,7 +178,7 @@ module BuildpackSupport
178
178
  end
179
179
 
180
180
  def from_mutable_cache(uri)
181
- cached_file = CachedFile.new(@mutable_cache_root, uri)
181
+ cached_file = CachedFile.new @mutable_cache_root, uri, true
182
182
  cached = update URI(uri), cached_file
183
183
  [cached_file, cached]
184
184
  rescue => e
@@ -188,7 +188,7 @@ module BuildpackSupport
188
188
 
189
189
  def from_immutable_caches(uri)
190
190
  @immutable_cache_roots.each do |cache_root|
191
- candidate = CachedFile.new cache_root, uri
191
+ candidate = CachedFile.new cache_root, uri, false
192
192
 
193
193
  next unless candidate.cached?
194
194
 
@@ -226,11 +226,11 @@ module BuildpackSupport
226
226
  request = Net::HTTP::Get.new(uri.request_uri)
227
227
 
228
228
  if cached_file.etag?
229
- cached_file.etag(File::RDONLY) { |f| request['If-None-Match'] = File.read(f) }
229
+ cached_file.etag(File::RDONLY | File::BINARY) { |f| request['If-None-Match'] = File.read(f) }
230
230
  end
231
231
 
232
232
  if cached_file.last_modified?
233
- cached_file.last_modified(File::RDONLY) { |f| request['If-Modified-Since'] = File.read(f) }
233
+ cached_file.last_modified(File::RDONLY | File::BINARY) { |f| request['If-Modified-Since'] = File.read(f) }
234
234
  end
235
235
 
236
236
  @logger.debug { "Request: #{request.path}, #{request.to_hash}" }
@@ -265,7 +265,7 @@ module BuildpackSupport
265
265
  def validate_size(expected_size, cached_file)
266
266
  return unless expected_size
267
267
 
268
- actual_size = cached_file.cached(File::RDONLY) { |f| f.size }
268
+ actual_size = cached_file.cached(File::RDONLY | File::BINARY) { |f| f.size }
269
269
  @logger.debug { "Validated content size #{actual_size} is #{expected_size}" }
270
270
 
271
271
  return if expected_size.to_i == actual_size
@@ -45,15 +45,34 @@ module BuildpackSupport
45
45
  #
46
46
  # @param [Boolean] available whether the internet is available
47
47
  # @param [String, nil] message an optional message to be printed when the availability is set
48
+ # @yields an environment with internet availability temporarily overridden if block given
48
49
  def available(available, message = nil)
49
50
  @monitor.synchronize do
50
- @available = available
51
- @logger.warn { "Internet availability set to #{available}: #{message}" } if message
51
+ if block_given?
52
+ preserve_availability do
53
+ @available = available
54
+ @logger.warn { "Internet availability temporarily set to #{available}: #{message}" } if message
55
+
56
+ yield
57
+ end
58
+ else
59
+ @available = available
60
+ @logger.warn { "Internet availability set to #{available}: #{message}" } if message
61
+ end
52
62
  end
53
63
  end
54
64
 
55
65
  private
56
66
 
67
+ def preserve_availability
68
+ previous = @available
69
+ begin
70
+ yield
71
+ ensure
72
+ @available = previous
73
+ end
74
+ end
75
+
57
76
  def remote_downloads?
58
77
  BuildpackSupport::ConfigurationUtils.new.load('cache')['remote_downloads'] != 'disabled'
59
78
  end
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  require 'spec_helper'
17
+ require 'buildpack_support/component/application'
17
18
  require 'buildpack_support/test/environment_helper'
18
19
  require 'buildpack_support/test/scratch_helper'
19
20
 
@@ -22,6 +22,7 @@ require 'buildpack_support/test/base_droplet_helper'
22
22
  require 'buildpack_support/test/console_helper'
23
23
  require 'buildpack_support/test/internet_availability_helper'
24
24
  require 'buildpack_support/test/logging_helper'
25
+ require 'buildpack_support/test/repository_helper'
25
26
  require 'buildpack_support/tokenized_version'
26
27
  require 'pathname'
27
28
 
@@ -31,6 +32,7 @@ shared_context 'base_component_helper' do
31
32
  include_context 'console_helper'
32
33
  include_context 'internet_availability_helper'
33
34
  include_context 'logging_helper'
35
+ include_context 'repository_helper'
34
36
 
35
37
  let(:application_cache) { double('ApplicationCache') }
36
38
 
@@ -0,0 +1,38 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2013-2014 the original author or authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'spec_helper'
17
+ require 'buildpack_support/repository/configured_item'
18
+ require 'buildpack_support/tokenized_version'
19
+
20
+ shared_context 'repository_helper' do
21
+
22
+ let(:configured_item) { double('configured_item') }
23
+
24
+ let(:uri) { 'test-uri' }
25
+
26
+ let(:version) { '0.0.0' }
27
+
28
+ before do
29
+ tokenized_version = BuildpackSupport::TokenizedVersion.new(version)
30
+
31
+ allow(BuildpackSupport::Repository::ConfiguredItem).to receive(:new).and_return configured_item
32
+
33
+ allow(configured_item).to receive(:find_item) do |&block|
34
+ block.call(tokenized_version) if block
35
+ end.and_return([tokenized_version, uri])
36
+ end
37
+
38
+ end
@@ -18,6 +18,6 @@ require 'buildpack_support'
18
18
  module BuildpackSupport
19
19
 
20
20
  # The version of the gem
21
- VERSION = '1.0.0'
21
+ VERSION = '1.1.0'
22
22
 
23
23
  end
@@ -22,12 +22,30 @@ require 'fileutils'
22
22
  describe BuildpackSupport::Cache::CachedFile do
23
23
  include_context 'scratch_helper'
24
24
 
25
- let(:file_cache) { described_class.new(scratch_dir, 'http://foo-uri/') }
25
+ let(:cache_root) { scratch_dir + 'cache/root' }
26
+
27
+ let(:file_cache) { described_class.new(scratch_dir, 'http://foo-uri/', true) }
26
28
 
27
29
  it 'should not create any files on initialization' do
28
30
  %w(cached etag last_modified).each { |extension| expect(cache_file(extension)).not_to exist }
29
31
  end
30
32
 
33
+ it 'should create cache_root if mutable' do
34
+ expect(cache_root).not_to exist
35
+
36
+ described_class.new(cache_root, 'http://foo-uri/', true)
37
+
38
+ expect(cache_root).to exist
39
+ end
40
+
41
+ it 'should not create cache_root if immutable' do
42
+ expect(cache_root).not_to exist
43
+
44
+ described_class.new(cache_root, 'http://foo-uri/', false)
45
+
46
+ expect(cache_root).not_to exist
47
+ end
48
+
31
49
  it 'should not detect cached file' do
32
50
  expect(file_cache.cached?).not_to be
33
51
  end
@@ -62,6 +80,12 @@ describe BuildpackSupport::Cache::CachedFile do
62
80
  %w(cached etag last_modified).each { |extension| expect(cache_file(extension)).not_to exist }
63
81
  end
64
82
 
83
+ it 'should not destroy all files if immutable' do
84
+ described_class.new(scratch_dir, 'http://foo-uri/', false).destroy
85
+
86
+ %w(cached etag last_modified).each { |extension| expect(cache_file(extension)).to exist }
87
+ end
88
+
65
89
  it 'should call the block with the content of the etag file' do
66
90
  expect { |b| file_cache.etag(File::RDONLY, 'test-arg', &b) }.to yield_file_with_content(/foo-etag/)
67
91
  end
@@ -80,7 +104,7 @@ describe BuildpackSupport::Cache::CachedFile do
80
104
  end
81
105
 
82
106
  def cache_file(extension)
83
- scratch_dir + "http:%2F%2Ffoo-uri%2F.#{extension}"
107
+ scratch_dir + "http%3A%2F%2Ffoo-uri%2F.#{extension}"
84
108
  end
85
109
 
86
110
  def touch(extension, content = '')
@@ -242,11 +242,11 @@ describe BuildpackSupport::Cache::DownloadCache do
242
242
  end
243
243
 
244
244
  def cache_file(root, extension)
245
- root + "http:%2F%2Ffoo-uri%2F.#{extension}"
245
+ root + "http%3A%2F%2Ffoo-uri%2F.#{extension}"
246
246
  end
247
247
 
248
248
  def credential_cache_file(root, extension)
249
- root + "http:%2F%2Ftest-username:test-password@foo-uri%2F.#{extension}"
249
+ root + "http%3A%2F%2Ftest-username%3Atest-password@foo-uri%2F.#{extension}"
250
250
  end
251
251
 
252
252
  def expect_complete_cache(root)
@@ -54,4 +54,22 @@ describe BuildpackSupport::Cache::InternetAvailability do
54
54
  expect(log_contents).to match(/Internet availability set to false: test message/)
55
55
  end
56
56
 
57
+ it 'should temporarily set internet unavailable' do
58
+ expect(described_class.instance.available?).to be
59
+
60
+ described_class.instance.available(false) { expect(described_class.instance.available?).not_to be }
61
+
62
+ expect(described_class.instance.available?).to be
63
+ end
64
+
65
+ it 'should temporarily set internet available',
66
+ :disable_internet do
67
+
68
+ expect(described_class.instance.available?).not_to be
69
+
70
+ described_class.instance.available(true) { expect(described_class.instance.available?).to be }
71
+
72
+ expect(described_class.instance.available?).not_to be
73
+ end
74
+
57
75
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buildpack-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-22 00:00:00.000000000 Z
12
+ date: 2014-05-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -261,6 +261,7 @@ files:
261
261
  - lib/buildpack_support/test/environment_helper.rb
262
262
  - lib/buildpack_support/test/internet_availability_helper.rb
263
263
  - lib/buildpack_support/test/logging_helper.rb
264
+ - lib/buildpack_support/test/repository_helper.rb
264
265
  - lib/buildpack_support/test/scratch_helper.rb
265
266
  - lib/buildpack_support/test/versioned_dependency_component_helper.rb
266
267
  - lib/buildpack_support/test/with_load_path_helper.rb
@@ -346,13 +347,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
346
347
  version: '0'
347
348
  segments:
348
349
  - 0
349
- hash: 3626864302089607718
350
+ hash: 2138916088248865313
350
351
  required_rubygems_version: !ruby/object:Gem::Requirement
351
352
  none: false
352
353
  requirements:
353
354
  - - ! '>='
354
355
  - !ruby/object:Gem::Version
355
356
  version: '0'
357
+ segments:
358
+ - 0
359
+ hash: 2138916088248865313
356
360
  requirements: []
357
361
  rubyforge_project:
358
362
  rubygems_version: 1.8.23.2