diff options
author | danielsdeleo <dan@opscode.com> | 2012-12-21 12:15:38 -0800 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2012-12-21 12:15:38 -0800 |
commit | 5c17ea2b59d87f806cc28abce594aee061ac0e69 (patch) | |
tree | 0c686878aa3f56727e8e801b56e66b6ffd3d4da2 | |
parent | eed92c71356f44afc03c575ca5aadff8023cb334 (diff) | |
parent | 72cf70f4495009e0f6fc8ab7e23b4eb8232d371b (diff) | |
download | chef-5c17ea2b59d87f806cc28abce594aee061ac0e69.tar.gz |
Merge branch 'CHEF-3715'
-rw-r--r-- | chef.gemspec | 3 | ||||
-rw-r--r-- | distro/common/markdown/man1/knife.mkd | 11 | ||||
-rw-r--r-- | lib/chef/checksum_cache.rb | 190 | ||||
-rw-r--r-- | lib/chef/config.rb | 20 | ||||
-rw-r--r-- | lib/chef/cookbook/syntax_check.rb | 75 | ||||
-rw-r--r-- | lib/chef/cookbook_uploader.rb | 2 | ||||
-rw-r--r-- | lib/chef/cookbook_version.rb | 2 | ||||
-rw-r--r-- | lib/chef/digester.rb | 73 | ||||
-rw-r--r-- | lib/chef/knife/configure.rb | 3 | ||||
-rw-r--r-- | lib/chef/knife/cookbook_test.rb | 1 | ||||
-rw-r--r-- | lib/chef/mixin/checksum.rb | 6 | ||||
-rw-r--r-- | lib/chef/monkey_patches/moneta.rb | 50 | ||||
-rw-r--r-- | spec/support/chef_helpers.rb | 2 | ||||
-rw-r--r-- | spec/unit/checksum_cache_spec.rb | 209 | ||||
-rw-r--r-- | spec/unit/cookbook/syntax_check_spec.rb | 157 | ||||
-rw-r--r-- | spec/unit/digester_spec.rb | 50 | ||||
-rw-r--r-- | spec/unit/mixin/checksum_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/provider/file_spec.rb | 59 | ||||
-rw-r--r-- | spec/unit/provider/template_spec.rb | 1 |
19 files changed, 288 insertions, 630 deletions
diff --git a/chef.gemspec b/chef.gemspec index fcf5d2b8ec..9de2822270 100644 --- a/chef.gemspec +++ b/chef.gemspec @@ -26,9 +26,8 @@ Gem::Specification.new do |s| s.add_dependency "net-ssh-multi", "~> 1.1.0" # CHEF-3027: The knife-cloud plugins require newer features from highline, core chef should not. s.add_dependency "highline", ">= 1.6.9" - %w{erubis moneta}.each { |gem| s.add_dependency gem } + s.add_dependency "erubis" - # development_dependency thin: eventmachine 0.12.10 doesn't support Ruby 1.9 on Windows %w(rdoc sdoc ronn rake rack rspec_junit_formatter).each { |gem| s.add_development_dependency gem } %w(rspec-core rspec-expectations rspec-mocks).each { |gem| s.add_development_dependency gem, "~> 2.8.0" } diff --git a/distro/common/markdown/man1/knife.mkd b/distro/common/markdown/man1/knife.mkd index 054e220cf9..8c97cc97e1 100644 --- a/distro/common/markdown/man1/knife.mkd +++ b/distro/common/markdown/man1/knife.mkd @@ -98,14 +98,9 @@ If the config file exists, knife uses these settings for __GENERAL OPTIONS__ def * `chef_server_url`: URL of the Chef server. Corresponds to the `-s` or `--server-url` option. This is requested from the user when running this sub-command. - * `cache_type`: - The type of cache to use. Default is BasicFile. This can be any type of - Cache that moneta supports: BasicFile, Berkeley, Couch, DataMapper, - File, LMC, Memcache, Memory, MongoDB, Redis, Rufus, S3, SDBM, Tyrant, - Xattr, YAML. - * `cache_options`: - Specifies various options to use for caching. These options are - dependent on the `cache_type`. + * `syntax_check_cache_path`: + Specifies the path to a directory where knife caches information + about files that it has syntax checked. * `validation_client_name`: Specifies the name of the client used to validate new clients. * `validation_key`: diff --git a/lib/chef/checksum_cache.rb b/lib/chef/checksum_cache.rb deleted file mode 100644 index 6db7115a56..0000000000 --- a/lib/chef/checksum_cache.rb +++ /dev/null @@ -1,190 +0,0 @@ -# -# Author:: Adam Jacob (<adam@opscode.com>) -# Author:: Daniel DeLeo (<dan@kallistec.com>) -# Copyright:: Copyright (c) 2009 Opscode, Inc. -# Copyright:: Copyright (c) 2009 Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'set' -require 'fileutils' -require 'chef/log' -require 'chef/config' -require 'chef/client' -require 'chef/mixin/convert_to_class_name' -require 'singleton' -require 'moneta' - -class Chef - class ChecksumCache - include Chef::Mixin::ConvertToClassName - include ::Singleton - - attr_reader :moneta - - def initialize(*args) - self.reset!(*args) - end - - def reset!(backend=nil, options=nil) - backend ||= Chef::Config[:cache_type] - options ||= Chef::Config[:cache_options] - - begin - require "moneta/#{convert_to_snake_case(backend, 'Moneta')}" - require 'chef/monkey_patches/moneta' - rescue LoadError => e - Chef::Log.fatal("Could not load Moneta back end #{backend.inspect}") - raise e - end - - @moneta = Moneta.const_get(backend).new(options) - end - - def self.reset_cache_validity - @valid_cached_checksums = nil - end - - Chef::Client.when_run_starts do |run_status| - reset_cache_validity - end - - def self.valid_cached_checksums - @valid_cached_checksums ||= Set.new - end - - def self.validate_checksum(checksum_key) - valid_cached_checksums << checksum_key - end - - def self.all_cached_checksums - all_checksums_with_filenames = {} - - Dir[File.join(Chef::Config[:cache_options][:path], '*')].each do |cksum_file| - all_checksums_with_filenames[File.basename(cksum_file)] = cksum_file - end - all_checksums_with_filenames - end - - def self.cleanup_checksum_cache - Chef::Log.debug("Cleaning the checksum cache") - if (Chef::Config[:cache_type].to_s == "BasicFile") - all_cached_checksums.each do |cache_key, cksum_cache_file| - unless valid_cached_checksums.include?(cache_key) - remove_unused_checksum(cksum_cache_file) - end - end - end - end - - Chef::Client.when_run_completes_successfully do |run_status| - cleanup_checksum_cache - end - - def self.remove_unused_checksum(checksum_file) - Chef::Log.debug("Removing unused checksum cache file #{checksum_file}") - FileUtils.rm(checksum_file) - end - - def self.checksum_for_file(*args) - instance.checksum_for_file(*args) - end - - def validate_checksum(*args) - self.class.validate_checksum(*args) - end - - def checksum_for_file(file, key=nil) - key ||= generate_key(file) - fstat = File.stat(file) - lookup_checksum(key, fstat) || generate_checksum(key, file, fstat) - end - - def lookup_checksum(key, fstat) - cached = fetch(key) - if cached && file_unchanged?(cached, fstat) - validate_checksum(key) - cached["checksum"] - else - nil - end - end - - def generate_checksum(key, file, fstat) - checksum = checksum_file(file, Digest::SHA256.new) - moneta.store(key, {"mtime" => fstat.mtime.to_f, "checksum" => checksum}) - validate_checksum(key) - checksum - end - - def generate_key(file, group="chef") - "#{group}-file-#{file.gsub(/(#{File::SEPARATOR}|\.)/, '-')}" - end - - def self.generate_md5_checksum_for_file(*args) - instance.generate_md5_checksum_for_file(*args) - end - - def generate_md5_checksum_for_file(file) - checksum_file(file, Digest::MD5.new) - end - - def generate_md5_checksum(io) - checksum_io(io, Digest::MD5.new) - end - - private - - def fetch(key) - @moneta.fetch(key) - rescue ArgumentError => e - Log.warn "Error loading cached checksum for key #{key.inspect}" - Log.warn(e) - repair_checksum_cache - nil - end - - def repair_checksum_cache - Chef::Log.info("Removing invalid checksum cache files") - Dir["#{Chef::Config[:cache_options][:path]}/*"].each do |file_path| - File.unlink(file_path) unless File.size?(file_path) - end - end - - def file_unchanged?(cached, fstat) - cached["mtime"].to_f == fstat.mtime.to_f - end - - def checksum_file(file, digest) - File.open(file, 'rb') { |f| checksum_io(f, digest) } - end - - def checksum_io(io, digest) - while chunk = io.read(1024 * 8) - digest.update(chunk) - end - digest.hexdigest - end - - end -end - -module Moneta - module Defaults - def default - nil - end - end -end diff --git a/lib/chef/config.rb b/lib/chef/config.rb index 85dce44474..d05692ddc8 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -48,9 +48,6 @@ class Chef end def self.platform_specific_path(path) - #10.times { puts "* " * 40} - #pp caller - if RUBY_PLATFORM =~ /mswin|mingw|windows/ # turns /etc/chef/client.rb into C:/chef/client.rb system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : "" @@ -309,10 +306,19 @@ class Chef # Start handlers start_handlers [] - # Checksum Cache - # Uses Moneta on the back-end - cache_type "BasicFile" - cache_options({ :path => platform_specific_path("/var/chef/cache/checksums"), :skip_expires => true }) + # Syntax Check Cache. Knife keeps track of files that is has already syntax + # checked by storing files in this directory. `syntax_check_cache_path` is + # the new (and preferred) configuration setting. If not set, knife will + # fall back to using cache_options[:path]. + # + # Because many users will have knife configs with cache_options (generated + # by `knife configure`), the default for now is to *not* set + # syntax_check_cache_path, and thus fallback to cache_options[:path]. We + # leave that value to the same default as was previously set. + syntax_check_cache_path nil + + # Deprecated: + cache_options({ :path => platform_specific_path("/var/chef/cache/checksums") }) # Set to false to silence Chef 11 deprecation warnings: chef11_deprecation_warnings true diff --git a/lib/chef/cookbook/syntax_check.rb b/lib/chef/cookbook/syntax_check.rb index bf7c45e252..40ba070796 100644 --- a/lib/chef/cookbook/syntax_check.rb +++ b/lib/chef/cookbook/syntax_check.rb @@ -16,8 +16,8 @@ # limitations under the License. # -require 'chef/checksum_cache' require 'chef/mixin/shell_out' +require 'chef/mixin/checksum' class Chef class Cookbook @@ -25,10 +25,65 @@ class Chef # Encapsulates the process of validating the ruby syntax of files in Chef # cookbooks. class SyntaxCheck + + # == Chef::Cookbook::SyntaxCheck::PersistentSet + # Implements set behavior with disk-based persistence. Objects in the set + # are expected to be strings containing only characters that are valid in + # filenames. + # + # This class is used to track which files have been syntax checked so + # that known good files are not rechecked. + class PersistentSet + + attr_reader :cache_path + + # Create a new PersistentSet. Values in the set are persisted by + # creating a file in the +cache_path+ directory. If not given, the + # value of Chef::Config[:syntax_check_cache_path] is used; if that + # value is not configured, the value of + # Chef::Config[:cache_options][:path] is used. + #-- + # history: prior to Chef 11, the cache implementation was based on + # moneta and configured via cache_options[:path]. Knife configs + # generated with Chef 11 will have `syntax_check_cache_path`, but older + # configs will have `cache_options[:path]`. `cache_options` is marked + # deprecated in chef/config.rb but doesn't currently trigger a warning. + # See also: CHEF-3715 + def initialize(cache_path=nil) + @cache_path = cache_path || Chef::Config[:syntax_check_cache_path] || Chef::Config[:cache_options][:path] + @cache_path_created = false + end + + # Adds +value+ to the set's collection. + def add(value) + ensure_cache_path_created + FileUtils.touch(File.join(cache_path, value)) + end + + # Returns true if the set includes +value+ + def include?(value) + File.exist?(File.join(cache_path, value)) + end + + private + + def ensure_cache_path_created + return true if @cache_path_created + FileUtils.mkdir_p(cache_path) + @cache_path_created = true + end + + end + include Chef::Mixin::ShellOut + include Chef::Mixin::Checksum attr_reader :cookbook_path + # A PersistentSet object that tracks which files have already been + # validated. + attr_reader :validated_files + # Creates a new SyntaxCheck given the +cookbook_name+ and a +cookbook_path+. # If no +cookbook_path+ is given, +Chef::Config.cookbook_path+ is used. def self.for_cookbook(cookbook_name, cookbook_path=nil) @@ -44,10 +99,7 @@ class Chef # cookbook_path::: the (on disk) path to the cookbook def initialize(cookbook_path) @cookbook_path = cookbook_path - end - - def cache - Chef::ChecksumCache.instance + @validated_files = PersistentSet.new end def ruby_files @@ -81,16 +133,11 @@ class Chef end def validated?(file) - !!cache.lookup_checksum(cache_key(file), File.stat(file)) + validated_files.include?(checksum(file)) end def validated(file) - cache.generate_checksum(cache_key(file), file, File.stat(file)) - end - - def cache_key(file) - @cache_keys ||= {} - @cache_keys[file] ||= cache.generate_key(file, "chef-test") + validated_files.add(checksum(file)) end def validate_ruby_files @@ -118,7 +165,7 @@ class Chef result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) } false end - + def validate_ruby_file(ruby_file) Chef::Log.debug("Testing #{ruby_file} for syntax errors...") result = shell_out("ruby -c #{ruby_file}") @@ -130,7 +177,7 @@ class Chef result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) } false end - + end end end diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb index 90c9ee9996..69be03731e 100644 --- a/lib/chef/cookbook_uploader.rb +++ b/lib/chef/cookbook_uploader.rb @@ -3,7 +3,7 @@ require 'set' require 'rest_client' require 'chef/exceptions' require 'chef/knife/cookbook_metadata' -require 'chef/checksum_cache' +require 'chef/digester' require 'chef/cookbook_version' require 'chef/cookbook/syntax_check' require 'chef/cookbook/file_system_file_vendor' diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 0e11174a07..580a64ffbe 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -69,7 +69,7 @@ class Chef # This is the one and only method that knows how cookbook files' # checksums are generated. def self.checksum_cookbook_file(filepath) - Chef::ChecksumCache.generate_md5_checksum_for_file(filepath) + Chef::Digester.generate_md5_checksum_for_file(filepath) rescue Errno::ENOENT Chef::Log.debug("File #{filepath} does not exist, so there is no checksum to generate") nil diff --git a/lib/chef/digester.rb b/lib/chef/digester.rb new file mode 100644 index 0000000000..669ff8b8a5 --- /dev/null +++ b/lib/chef/digester.rb @@ -0,0 +1,73 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Daniel DeLeo (<dan@kallistec.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# Copyright:: Copyright (c) 2009 Daniel DeLeo +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'digest' + +class Chef + class Digester + + def self.instance + @instance ||= new + end + + def self.checksum_for_file(*args) + instance.checksum_for_file(*args) + end + + def validate_checksum(*args) + self.class.validate_checksum(*args) + end + + def checksum_for_file(file) + generate_checksum(file) + end + + def generate_checksum(file) + checksum_file(file, Digest::SHA256.new) + end + + def self.generate_md5_checksum_for_file(*args) + instance.generate_md5_checksum_for_file(*args) + end + + def generate_md5_checksum_for_file(file) + checksum_file(file, Digest::MD5.new) + end + + def generate_md5_checksum(io) + checksum_io(io, Digest::MD5.new) + end + + private + + def checksum_file(file, digest) + File.open(file, 'rb') { |f| checksum_io(f, digest) } + end + + def checksum_io(io, digest) + while chunk = io.read(1024 * 8) + digest.update(chunk) + end + digest.hexdigest + end + + end +end + diff --git a/lib/chef/knife/configure.rb b/lib/chef/knife/configure.rb index 0be7093e29..e818239a89 100644 --- a/lib/chef/knife/configure.rb +++ b/lib/chef/knife/configure.rb @@ -81,8 +81,7 @@ client_key '#{new_client_key}' validation_client_name '#{validation_client_name}' validation_key '#{validation_key}' chef_server_url '#{chef_server}' -cache_type 'BasicFile' -cache_options( :path => '#{File.join(chef_config_path, "checksums")}' ) +syntax_check_cache_path '#{File.join(chef_config_path, "syntax_check_cache")}' EOH unless chef_repo.empty? f.puts "cookbook_path [ '#{chef_repo}/cookbooks' ]" diff --git a/lib/chef/knife/cookbook_test.rb b/lib/chef/knife/cookbook_test.rb index dc8f12d135..b84ab9b5b4 100644 --- a/lib/chef/knife/cookbook_test.rb +++ b/lib/chef/knife/cookbook_test.rb @@ -25,7 +25,6 @@ class Chef class CookbookTest < Knife deps do - require 'chef/checksum_cache' require 'chef/cookbook/syntax_check' end diff --git a/lib/chef/mixin/checksum.rb b/lib/chef/mixin/checksum.rb index 7b716b6285..8217296915 100644 --- a/lib/chef/mixin/checksum.rb +++ b/lib/chef/mixin/checksum.rb @@ -17,16 +17,16 @@ # require 'digest/sha2' -require 'chef/checksum_cache' +require 'chef/digester' class Chef module Mixin module Checksum def checksum(file) - Chef::ChecksumCache.checksum_for_file(file) + Chef::Digester.checksum_for_file(file) end - + end end end diff --git a/lib/chef/monkey_patches/moneta.rb b/lib/chef/monkey_patches/moneta.rb deleted file mode 100644 index 1c2895db56..0000000000 --- a/lib/chef/monkey_patches/moneta.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -# Author:: Seth Chisamore (<schisamo@opscode.com>) -# Copyright:: Copyright (c) 2011 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# ensure data is written and read in binary mode -# stops "dump format error for symbol(0x75)" errors -module Moneta - class BasicFile - - def store(key, value, options = {}) - ensure_directory_created(::File.dirname(path(key))) - ::File.open(path(key), "wb") do |file| - if @expires - data = {:value => value} - if options[:expires_in] - data[:expires_at] = Time.now + options[:expires_in] - end - contents = Marshal.dump(data) - else - contents = Marshal.dump(value) - end - file.puts(contents) - end - end - - def raw_get(key) - if ::File.respond_to?(:binread) - data = ::File.binread(path(key)) - else - data = ::File.open(path(key),"rb") { |f| f.read } - end - Marshal.load(data) - end - - end -end diff --git a/spec/support/chef_helpers.rb b/spec/support/chef_helpers.rb index 77cbe5b5cb..74af5f558e 100644 --- a/spec/support/chef_helpers.rb +++ b/spec/support/chef_helpers.rb @@ -17,8 +17,6 @@ CHEF_SPEC_DATA = File.expand_path(File.dirname(__FILE__) + "/../data/") CHEF_SPEC_BACKUP_PATH = File.join(Dir.tmpdir, 'test-backup-path') Chef::Config[:log_level] = :fatal -Chef::Config[:cache_type] = "Memory" -Chef::Config[:cache_options] = { } Chef::Config[:persistent_queue] = false Chef::Config[:file_backup_path] = CHEF_SPEC_BACKUP_PATH diff --git a/spec/unit/checksum_cache_spec.rb b/spec/unit/checksum_cache_spec.rb deleted file mode 100644 index 78e76b6dfb..0000000000 --- a/spec/unit/checksum_cache_spec.rb +++ /dev/null @@ -1,209 +0,0 @@ -# -# Author:: Adam Jacob (<adam@opscode.com>) -# Author:: Daniel DeLeo (<dan@kallistec.com>) -# Copyright:: Copyright (c) 2009 Opscode, Inc. -# Copyright:: Copyright (c) 2009 Daniel DeLeo -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'spec_helper' - -describe Chef::ChecksumCache do - before(:each) do - Chef::Config[:cache_type] = "Memory" - Chef::Config[:cache_options] = { } - @cache = Chef::ChecksumCache.instance - @cache.reset! - end - - describe "loading the moneta backend" do - it "should build a Chef::ChecksumCache object" do - @cache.should be_a_kind_of(Chef::ChecksumCache) - end - - it "should set up a Moneta Cache adaptor" do - @cache.moneta.should be_a_kind_of(Moneta::Memory) - end - - it "should raise an exception if it cannot load the moneta adaptor" do - Chef::Log.should_receive(:fatal).with(/^Could not load Moneta back end/) - lambda { - c = Chef::ChecksumCache.instance.reset!('WTF') - }.should raise_error(LoadError) - end - end - - describe "when caching checksums of cookbook files and templates" do - - before do - @cache.reset!("Memory", {}) - end - - it "proxies the class method checksum_for_file to the instance" do - @cache.should_receive(:checksum_for_file).with("a_file_or_a_fail") - Chef::ChecksumCache.checksum_for_file("a_file_or_a_fail") - end - - it "returns a cached checksum value" do - @cache.moneta["chef-file-riseofthemachines"] = {"mtime" => "12345", "checksum" => "123abc"} - fstat = mock("File.stat('riseofthemachines')", :mtime => Time.at(12345)) - File.should_receive(:stat).with("riseofthemachines").and_return(fstat) - @cache.checksum_for_file("riseofthemachines").should == "123abc" - end - - it "gives nil for a cache miss" do - @cache.moneta["chef-file-riseofthemachines"] = {"mtime" => "12345", "checksum" => "123abc"} - fstat = mock("File.stat('riseofthemachines')", :mtime => Time.at(555555)) - @cache.lookup_checksum("chef-file-riseofthemachines", fstat).should be_nil - end - - it "treats a non-matching mtime as a cache miss" do - @cache.moneta["chef-file-riseofthemachines"] = {"mtime" => "12345", "checksum" => "123abc"} - fstat = mock("File.stat('riseofthemachines')", :mtime => Time.at(555555)) - @cache.lookup_checksum("chef-file-riseofthemachines", fstat).should be_nil - end - - it "computes a checksum of a file" do - fixture_file = CHEF_SPEC_DATA + "/checksum/random.txt" - expected = "09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394" - @cache.send(:checksum_file, fixture_file, Digest::SHA256.new).should == expected - end - - it "computes a checksum and stores it in the cache" do - fstat = mock("File.stat('riseofthemachines')", :mtime => Time.at(555555)) - @cache.should_receive(:checksum_file).with("riseofthemachines", an_instance_of(Digest::SHA256)).and_return("ohai2uChefz") - @cache.generate_checksum("chef-file-riseofthemachines", "riseofthemachines", fstat).should == "ohai2uChefz" - @cache.lookup_checksum("chef-file-riseofthemachines", fstat).should == "ohai2uChefz" - end - - it "returns a generated checksum if there is no cached value" do - fixture_file = CHEF_SPEC_DATA + "/checksum/random.txt" - expected = "09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394" - @cache.checksum_for_file(fixture_file).should == expected - end - - it "generates a key from a file name" do - file = "/this/is/a/test/random.rb" - @cache.generate_key(file).should == "chef-file--this-is-a-test-random-rb" - end - - it "generates a key from a file name and group" do - file = "/this/is/a/test/random.rb" - @cache.generate_key(file, "spec").should == "spec-file--this-is-a-test-random-rb" - end - - it "returns a cached checksum value using a user defined key" do - key = @cache.generate_key("riseofthemachines", "specs") - @cache.moneta[key] = {"mtime" => "12345", "checksum" => "123abc"} - fstat = mock("File.stat('riseofthemachines')", :mtime => Time.at(12345)) - File.should_receive(:stat).with("riseofthemachines").and_return(fstat) - @cache.checksum_for_file("riseofthemachines", key).should == "123abc" - end - - it "generates a checksum from a non-file IO object" do - io = StringIO.new("riseofthemachines\nriseofthechefs\n") - expected_md5 = '0e157ac1e2dd73191b76067fb6b4bceb' - @cache.generate_md5_checksum(io).should == expected_md5 - end - - end - - describe "when cleaning up after outdated checksums" do - - before do - Chef::ChecksumCache.reset_cache_validity - end - - it "initially has no valid cached checksums" do - Chef::ChecksumCache.valid_cached_checksums.should be_empty - end - - it "adds a checksum to the list of valid cached checksums when it's created" do - @cache.checksum_for_file(File.join(CHEF_SPEC_DATA, 'checksum', 'random.txt')) - Chef::ChecksumCache.valid_cached_checksums.should have(1).valid_checksum - end - - it "adds a checksum to the list of valid cached checksums when it's read" do - @cache.checksum_for_file(File.join(CHEF_SPEC_DATA, 'checksum', 'random.txt')) - Chef::ChecksumCache.reset_cache_validity - @cache.checksum_for_file(File.join(CHEF_SPEC_DATA, 'checksum', 'random.txt')) - Chef::ChecksumCache.valid_cached_checksums.should have(1).valid_checksum - end - - context "with an existing set of cached checksums" do - before do - Chef::Config[:cache_type] = "BasicFile" - Chef::Config[:cache_options] = {:path => File.join(CHEF_SPEC_DATA, "checksum_cache")} - - @expected_cached_checksums = ["chef-file--tmp-chef-rendered-template20100929-10863-600hhz-0", - "chef-file--tmp-chef-rendered-template20100929-10863-6m8zdk-0", - "chef-file--tmp-chef-rendered-template20100929-10863-ahd2gq-0", - "chef-file--tmp-chef-rendered-template20100929-10863-api8ux-0", - "chef-file--tmp-chef-rendered-template20100929-10863-b0r1m1-0", - "chef-file--tmp-chef-rendered-template20100929-10863-bfygsi-0", - "chef-file--tmp-chef-rendered-template20100929-10863-el14l6-0", - "chef-file--tmp-chef-rendered-template20100929-10863-ivrl3y-0", - "chef-file--tmp-chef-rendered-template20100929-10863-kkbs85-0", - "chef-file--tmp-chef-rendered-template20100929-10863-ory1ux-0", - "chef-file--tmp-chef-rendered-template20100929-10863-pgsq76-0", - "chef-file--tmp-chef-rendered-template20100929-10863-ra8uim-0", - "chef-file--tmp-chef-rendered-template20100929-10863-t7k1g-0", - "chef-file--tmp-chef-rendered-template20100929-10863-t8g0sv-0", - "chef-file--tmp-chef-rendered-template20100929-10863-ufy6g3-0", - "chef-file--tmp-chef-rendered-template20100929-10863-x2d6j9-0", - "chef-file--tmp-chef-rendered-template20100929-10863-xi0l6h-0"] - @expected_cached_checksums.sort! - end - - after do - Chef::Config[:cache_type] = "Memory" - Chef::Config[:cache_options] = { } - @cache = Chef::ChecksumCache.instance - @cache.reset! - end - - it "lists all of the cached checksums in the cache directory" do - Chef::ChecksumCache.all_cached_checksums.keys.sort.should == @expected_cached_checksums - end - - it "clears all of the checksums not marked valid from the checksums directory" do - valid_cksum_key = "chef-file--tmp-chef-rendered-template20100929-10863-ivrl3y-0" - valid_cksum_file = File.join(CHEF_SPEC_DATA, "checksum_cache", valid_cksum_key) - @expected_cached_checksums.delete(valid_cksum_key) - - Chef::ChecksumCache.valid_cached_checksums << valid_cksum_key - - Chef::ChecksumCache.should_not_receive(:remove_unused_checksum).with(valid_cksum_file) - @expected_cached_checksums.each do |cksum_key| - full_path_to_cksum = File.join(CHEF_SPEC_DATA, "checksum_cache", cksum_key) - Chef::ChecksumCache.should_receive(:remove_unused_checksum).with(full_path_to_cksum) - end - - Chef::ChecksumCache.cleanup_checksum_cache - end - - it "cleans all 0byte checksum files when it encounters a Marshal error" do - @cache.moneta.stub!(:fetch).and_raise(ArgumentError) - # This cache file is 0 bytes, raises an argument error when - # attempting to Marshal.load - File.should_receive(:unlink).with(File.join(CHEF_SPEC_DATA, "checksum_cache", "chef-file--tmp-chef-rendered-template20100929-10863-6m8zdk-0")) - @cache.lookup_checksum("chef-file--tmp-chef-rendered-template20100929-10863-6m8zdk-0", "foo") - end - end - - end - -end - diff --git a/spec/unit/cookbook/syntax_check_spec.rb b/spec/unit/cookbook/syntax_check_spec.rb index b41c2ddf0a..948b3c5a38 100644 --- a/spec/unit/cookbook/syntax_check_spec.rb +++ b/spec/unit/cookbook/syntax_check_spec.rb @@ -16,175 +16,114 @@ # limitations under the License. # -################################################### -# OLD: -################################################### -# def test_ruby(cookbook_dir) -# cache = Chef::ChecksumCache.instance -# Dir[File.join(cookbook_dir, '**', '*.rb')].each do |ruby_file| -# key = cache.generate_key(ruby_file, "chef-test") -# fstat = File.stat(ruby_file) -# -# if cache.lookup_checksum(key, fstat) -# Chef::Log.info("No change in checksum of #{ruby_file}") -# else -# Chef::Log.info("Testing #{ruby_file} for syntax errors...") -# Chef::Mixin::Command.run_command(:command => "ruby -c #{ruby_file}", :output_on_failure => true) -# cache.generate_checksum(key, ruby_file, fstat) -# end -# end -# end -# -#def test_templates(cookbook_dir) -# cache = Chef::ChecksumCache.instance -# Dir[File.join(cookbook_dir, '**', '*.erb')].each do |erb_file| -# key = cache.generate_key(erb_file, "chef-test") -# fstat = File.stat(erb_file) -# -# if cache.lookup_checksum(key, fstat) -# Chef::Log.info("No change in checksum of #{erb_file}") -# else -# Chef::Log.info("Testing template #{erb_file} for syntax errors...") -# Chef::Mixin::Command.run_command(:command => "sh -c 'erubis -x #{erb_file} | ruby -c'", :output_on_failure => true) -# cache.generate_checksum(key, erb_file, fstat) -# end -# end -#end -# - -################################################### -# NEW: -################################################### -# def test_template_file(cookbook_dir, erb_file) -# Chef::Log.debug("Testing template #{erb_file} for syntax errors...") -# result = shell_out("sh -c 'erubis -x #{erb_file} | ruby -c'") -# result.error! -# rescue Mixlib::ShellOut::ShellCommandFailed -# file_relative_path = erb_file[/^#{Regexp.escape(cookbook_dir+File::Separator)}(.*)/, 1] -# Chef::Log.fatal("Erb template #{file_relative_path} has a syntax error:") -# result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) } -# exit(1) -# end -# -# def test_ruby_file(cookbook_dir, ruby_file) -# Chef::Log.debug("Testing #{ruby_file} for syntax errors...") -# result = shell_out("ruby -c #{ruby_file}") -# result.error! -# rescue Mixlib::ShellOut::ShellCommandFailed -# file_relative_path = ruby_file[/^#{Regexp.escape(cookbook_dir+File::Separator)}(.*)/, 1] -# Chef::Log.fatal("Cookbook file #{file_relative_path} has a syntax error:") -# result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) } -# exit(1) -# end -# - require 'spec_helper' require "chef/cookbook/syntax_check" describe Chef::Cookbook::SyntaxCheck do + + let(:cookbook_path) { File.join(CHEF_SPEC_DATA, 'cookbooks', 'openldap') } + let(:syntax_check) { Chef::Cookbook::SyntaxCheck.new(cookbook_path) } + before do Chef::Log.logger = Logger.new(StringIO.new) + Chef::Log.level = :warn # suppress "Syntax OK" messages - @cookbook_path = File.join(CHEF_SPEC_DATA, 'cookbooks', 'openldap') - @attr_files = %w{default.rb smokey.rb}.map { |f| File.join(@cookbook_path, 'attributes', f) } - @defn_files = %w{client.rb server.rb}.map { |f| File.join(@cookbook_path, 'definitions', f)} - @recipes = %w{default.rb gigantor.rb one.rb}.map { |f| File.join(@cookbook_path, 'recipes', f) } + @attr_files = %w{default.rb smokey.rb}.map { |f| File.join(cookbook_path, 'attributes', f) } + @defn_files = %w{client.rb server.rb}.map { |f| File.join(cookbook_path, 'definitions', f)} + @recipes = %w{default.rb gigantor.rb one.rb}.map { |f| File.join(cookbook_path, 'recipes', f) } @ruby_files = @attr_files + @defn_files + @recipes - @template_files = %w{openldap_stuff.conf.erb openldap_variable_stuff.conf.erb test.erb}.map { |f| File.join(@cookbook_path, 'templates', 'default', f)} + @template_files = %w{openldap_stuff.conf.erb openldap_variable_stuff.conf.erb test.erb}.map { |f| File.join(cookbook_path, 'templates', 'default', f)} - @syntax_check = Chef::Cookbook::SyntaxCheck.new(@cookbook_path) end it "creates a syntax checker given the cookbook name when Chef::Config.cookbook_path is set" do - Chef::Config[:cookbook_path] = File.dirname(@cookbook_path) + Chef::Config[:cookbook_path] = File.dirname(cookbook_path) syntax_check = Chef::Cookbook::SyntaxCheck.for_cookbook(:openldap) - syntax_check.cookbook_path.should == @cookbook_path + syntax_check.cookbook_path.should == cookbook_path end describe "when first created" do it "has the path to the cookbook to syntax check" do - @syntax_check.cookbook_path.should == @cookbook_path - end - - it "has access to the checksum cache" do - @syntax_check.cache.should equal(Chef::ChecksumCache.instance) + syntax_check.cookbook_path.should == cookbook_path end it "lists the ruby files in the cookbook" do - @syntax_check.ruby_files.sort.should == @ruby_files.sort + syntax_check.ruby_files.sort.should == @ruby_files.sort end it "lists the erb templates in the cookbook" do - @syntax_check.template_files.sort.should == @template_files.sort + syntax_check.template_files.sort.should == @template_files.sort end end describe "when validating cookbooks" do + let(:cache_path) { Dir.mktmpdir } + before do - Chef::Config[:cache_type] = 'Memory' - @checksum_cache_klass = Class.new(Chef::ChecksumCache) - @checksum_cache = @checksum_cache_klass.instance - @checksum_cache.reset!('Memory') - @syntax_check.stub!(:cache).and_return(@checksum_cache) - $stdout.stub!(:write) + Chef::Config[:syntax_check_cache_path] = cache_path + end + + after do + FileUtils.rm_rf(cache_path) if File.exist?(cache_path) + Chef::Config[:syntax_check_cache_path] = nil end describe "and the files have not been syntax checked previously" do it "shows that all ruby files require a syntax check" do - @syntax_check.untested_ruby_files.sort.should == @ruby_files.sort + syntax_check.untested_ruby_files.sort.should == @ruby_files.sort end it "shows that all template files require a syntax check" do - @syntax_check.untested_template_files.sort.should == @template_files.sort + syntax_check.untested_template_files.sort.should == @template_files.sort end it "removes a ruby file from the list of untested files after it is marked as validated" do - recipe = File.join(@cookbook_path, 'recipes', 'default.rb') - @syntax_check.validated(recipe) - @syntax_check.untested_ruby_files.should_not include(recipe) + recipe = File.join(cookbook_path, 'recipes', 'default.rb') + syntax_check.validated(recipe) + syntax_check.untested_ruby_files.should_not include(recipe) end it "removes a template file from the list of untested files after it is marked as validated" do - template = File.join(@cookbook_path, 'templates', 'default', 'test.erb') - @syntax_check.validated(template) - @syntax_check.untested_template_files.should_not include(template) + template = File.join(cookbook_path, 'templates', 'default', 'test.erb') + syntax_check.validated(template) + syntax_check.untested_template_files.should_not include(template) end it "validates all ruby files" do - @syntax_check.validate_ruby_files.should be_true - @syntax_check.untested_ruby_files.should be_empty + syntax_check.validate_ruby_files.should be_true + syntax_check.untested_ruby_files.should be_empty end it "validates all templates" do - @syntax_check.validate_templates.should be_true - @syntax_check.untested_template_files.should be_empty + syntax_check.validate_templates.should be_true + syntax_check.untested_template_files.should be_empty end describe "and a file has a syntax error" do before do - @cookbook_path = File.join(CHEF_SPEC_DATA, 'cookbooks', 'borken') - @syntax_check.cookbook_path.replace(@cookbook_path) + cookbook_path = File.join(CHEF_SPEC_DATA, 'cookbooks', 'borken') + syntax_check.cookbook_path.replace(cookbook_path) end it "it indicates that a ruby file has a syntax error" do - @syntax_check.validate_ruby_files.should be_false + syntax_check.validate_ruby_files.should be_false end it "does not remove the invalid file from the list of untested files" do - @syntax_check.untested_ruby_files.should include(File.join(@cookbook_path, 'recipes', 'default.rb')) - lambda { @syntax_check.validate_ruby_files }.should_not change(@syntax_check, :untested_ruby_files) + syntax_check.untested_ruby_files.should include(File.join(cookbook_path, 'recipes', 'default.rb')) + lambda { syntax_check.validate_ruby_files }.should_not change(syntax_check, :untested_ruby_files) end it "indicates that a template file has a syntax error" do - @syntax_check.validate_templates.should be_false + syntax_check.validate_templates.should be_false end it "does not remove the invalid template from the list of untested templates" do - @syntax_check.untested_template_files.should include(File.join(@cookbook_path, 'templates', 'default', 'borken.erb')) - lambda {@syntax_check.validate_templates}.should_not change(@syntax_check, :untested_template_files) + syntax_check.untested_template_files.should include(File.join(cookbook_path, 'templates', 'default', 'borken.erb')) + lambda {syntax_check.validate_templates}.should_not change(syntax_check, :untested_template_files) end end @@ -193,18 +132,18 @@ describe Chef::Cookbook::SyntaxCheck do describe "and the files have been syntax checked previously" do before do - @syntax_check.untested_ruby_files.each { |f| @syntax_check.validated(f) } - @syntax_check.untested_template_files.each { |f| @syntax_check.validated(f) } + syntax_check.untested_ruby_files.each { |f| syntax_check.validated(f) } + syntax_check.untested_template_files.each { |f| syntax_check.validated(f) } end it "does not syntax check ruby files" do - @syntax_check.should_not_receive(:shell_out) - @syntax_check.validate_ruby_files.should be_true + syntax_check.should_not_receive(:shell_out) + syntax_check.validate_ruby_files.should be_true end it "does not syntax check templates" do - @syntax_check.should_not_receive(:shell_out) - @syntax_check.validate_templates.should be_true + syntax_check.should_not_receive(:shell_out) + syntax_check.validate_templates.should be_true end end end diff --git a/spec/unit/digester_spec.rb b/spec/unit/digester_spec.rb new file mode 100644 index 0000000000..28e3e918fe --- /dev/null +++ b/spec/unit/digester_spec.rb @@ -0,0 +1,50 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Author:: Daniel DeLeo (<dan@kallistec.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# Copyright:: Copyright (c) 2009 Daniel DeLeo +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'spec_helper' + +describe Chef::Digester do + before(:each) do + @cache = Chef::Digester.instance + end + + describe "when computing checksums of cookbook files and templates" do + + it "proxies the class method checksum_for_file to the instance" do + @cache.should_receive(:checksum_for_file).with("a_file_or_a_fail") + Chef::Digester.checksum_for_file("a_file_or_a_fail") + end + + it "computes a checksum of a file" do + fixture_file = CHEF_SPEC_DATA + "/checksum/random.txt" + expected = "09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394" + @cache.checksum_for_file(fixture_file).should == expected + end + + it "generates a checksum from a non-file IO object" do + io = StringIO.new("riseofthemachines\nriseofthechefs\n") + expected_md5 = '0e157ac1e2dd73191b76067fb6b4bceb' + @cache.generate_md5_checksum(io).should == expected_md5 + end + + end + +end + diff --git a/spec/unit/mixin/checksum_spec.rb b/spec/unit/mixin/checksum_spec.rb index dec270e18f..19af1c7d2b 100644 --- a/spec/unit/mixin/checksum_spec.rb +++ b/spec/unit/mixin/checksum_spec.rb @@ -27,12 +27,12 @@ end describe Chef::Mixin::Checksum do before(:each) do @checksum_user = Chef::CMCCheck.new - @cache = Chef::ChecksumCache.instance + @cache = Chef::Digester.instance @file = CHEF_SPEC_DATA + "/checksum/random.txt" @stat = mock("File::Stat", { :mtime => Time.at(0) }) File.stub!(:stat).and_return(@stat) end - + it "gets the checksum of a file" do @checksum_user.checksum(@file).should == "09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394" end diff --git a/spec/unit/provider/file_spec.rb b/spec/unit/provider/file_spec.rb index 23352a5124..8c575e815e 100644 --- a/spec/unit/provider/file_spec.rb +++ b/spec/unit/provider/file_spec.rb @@ -56,68 +56,68 @@ describe Chef::Provider::File do context "load_current_resource_attrs", :unix_only do it "should collect the current state of the file on the filesystem and populate current_resource" do # test setup - stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) - ::File.should_receive(:stat).exactly(3).with(@resource.path).and_return(stat_struct) - - # test execution + stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) + ::File.should_receive(:stat).exactly(2).times.with(@resource.path).and_return(stat_struct) + + # test execution @provider.load_current_resource - + # post-condition checks @provider.current_resource.mode.should == 0600 @provider.current_resource.owner.should == 0 @provider.current_resource.group.should == 0 end - + it "should NOT update the new_resource state with the current_resourse state if new_resource state is already specified" do # test setup - stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) - ::File.should_receive(:stat).exactly(3).with(@resource.path).and_return(stat_struct) - + stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) + ::File.should_receive(:stat).exactly(2).times.with(@resource.path).and_return(stat_struct) + @provider.new_resource.group(1) @provider.new_resource.owner(1) @provider.new_resource.mode(0644) - - # test execution + + # test execution @provider.load_current_resource - + # post-condition checks @provider.new_resource.group.should == 1 @provider.new_resource.owner.should == 1 @provider.new_resource.mode.should == 0644 end - + it "should update the new_resource state with the current_resource state if the new_resource state is not specified." do # test setup - stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) - ::File.should_receive(:stat).exactly(3).with(@resource.path).and_return(stat_struct) - + stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) + ::File.should_receive(:stat).exactly(2).times.with(@resource.path).and_return(stat_struct) + @provider.new_resource.group(nil) @provider.new_resource.owner(nil) @provider.new_resource.mode(nil) - - # test execution + + # test execution @provider.load_current_resource - + # post-condition checks @provider.new_resource.group.should eql(@provider.current_resource.group) @provider.new_resource.owner.should eql(@provider.current_resource.owner) @provider.new_resource.mode.should eql(@provider.current_resource.mode) end - + it "should update the new_resource when attempting to set the new state" do # test setup - stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) + stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000) # called once in update_new_file_state and once in checksum - ::File.should_receive(:stat).twice.with(@provider.new_resource.path).and_return(stat_struct) + ::File.should_receive(:stat).with(@provider.new_resource.path).and_return(stat_struct) ::File.should_receive(:directory?).once.with(@provider.new_resource.path).and_return(false) - + @provider.new_resource.group(nil) @provider.new_resource.owner(nil) @provider.new_resource.mode(nil) - - # test exectution + + # test exectution @provider.update_new_file_state - + # post-condition checks @provider.new_resource.group.should == 0 @provider.new_resource.owner.should == 0 @@ -174,6 +174,8 @@ describe Chef::Provider::File do @provider.new_resource.content "foobar" @provider.should_receive(:diff_current_from_content).and_return("") @provider.should_receive(:backup) + # checksum check + File.should_receive(:open).with(@provider.new_resource.path, "rb").and_yield(io) File.should_receive(:open).with(@provider.new_resource.path, "w").and_yield(io) @provider.set_content io.string.should == "foobar" @@ -182,7 +184,8 @@ describe Chef::Provider::File do it "should not set the content of the file if it already matches the requested content" do @provider.load_current_resource @provider.new_resource.content IO.read(@resource.path) - File.stub!(:open).and_return(1) + # Checksum check: + File.should_receive(:open).with(@resource.path, "rb").and_yield(StringIO.new(@resource.content)) File.should_not_receive(:open).with(@provider.new_resource.path, "w") lambda { @provider.set_content }.should_not raise_error @resource.should_not be_updated_by_last_action @@ -487,7 +490,7 @@ describe Chef::Provider::File do it "should return valid diff output when content does not match the string content provided" do Tempfile.open("some-temp") do |file| @resource.path file.path - @provider = Chef::Provider::File.new(@resource, @run_context) + @provider = Chef::Provider::File.new(@resource, @run_context) @provider.load_current_resource result = @provider.diff_current_from_content "foo baz" # remove the file name info which varies. diff --git a/spec/unit/provider/template_spec.rb b/spec/unit/provider/template_spec.rb index 6747876d61..f5d30f0219 100644 --- a/spec/unit/provider/template_spec.rb +++ b/spec/unit/provider/template_spec.rb @@ -156,7 +156,6 @@ describe Chef::Provider::Template do describe "when the target has the correct content" do before do - Chef::ChecksumCache.instance.reset! File.open(@rendered_file_location, "w") { |f| f.print "slappiness is a warm gun" } @current_resource.checksum('4ff94a87794ed9aefe88e734df5a66fc8727a179e9496cbd88e3b5ec762a5ee9') @access_controls = mock("access controls") |