文件操作 - inifile_spec.rb
返回文件管理
返回主菜单
删除本文件
文件: /opt/puppetlabs/puppet/vendor_modules/yumrepo_core/spec/unit/provider/yumrepo/inifile_spec.rb
编辑文件内容
require 'spec_helper' require 'puppet_spec/files' require 'puppet_spec/compiler' describe Puppet::Type.type(:yumrepo).provider(:inifile) do include PuppetSpec::Files include PuppetSpec::Compiler after(:each) do described_class.clear end describe 'enumerating all yum repo files' do it 'reads all files in the directories specified by reposdir' do expect(described_class).to receive(:reposdir).and_return ['/etc/yum.repos.d'] expect(Dir).to receive(:glob).with('/etc/yum.repos.d/*.repo').and_return(['/etc/yum.repos.d/first.repo', '/etc/yum.repos.d/second.repo']) actual = described_class.repofiles expect(actual).to include('/etc/yum.repos.d/first.repo') expect(actual).to include('/etc/yum.repos.d/second.repo') end it "includes '/etc/yum.conf' as the first element" do expect(described_class).to receive(:reposdir).and_return [] actual = described_class.repofiles expect(actual[0]).to eq '/etc/yum.conf' end end describe 'generating the virtual inifile' do let(:files) { ['/etc/yum.repos.d/first.repo', '/etc/yum.repos.d/second.repo', '/etc/yum.conf'] } let(:collection) { instance_double('Puppet::Provider::Yumrepo::IniConfig::FileCollection') } before(:each) do described_class.clear allow(Puppet::Provider::Yumrepo::IniConfig::FileCollection).to receive(:new).and_return collection end it 'reads all files in the directories specified by self.repofiles' do expect(described_class).to receive(:repofiles).and_return(files) files.each do |file| allow(Puppet::FileSystem).to receive(:file?).with(file).and_return true expect(collection).to receive(:read).with(file) end described_class.virtual_inifile end it 'ignores repofile entries that are not files' do expect(described_class).to receive(:repofiles).and_return(files) allow(Puppet::FileSystem).to receive(:file?).with('/etc/yum.repos.d/first.repo').and_return true allow(Puppet::FileSystem).to receive(:file?).with('/etc/yum.repos.d/second.repo').and_return false allow(Puppet::FileSystem).to receive(:file?).with('/etc/yum.conf').and_return true expect(collection).to receive(:read).with('/etc/yum.repos.d/first.repo').once expect(collection).to receive(:read).with('/etc/yum.repos.d/second.repo').never expect(collection).to receive(:read).with('/etc/yum.conf').once described_class.virtual_inifile end end describe 'creating provider instances' do let(:virtual_inifile) { instance_double('Puppet::Provider::Yumrepo::IniConfig::FileCollection') } let(:main_section) do sect = Puppet::Provider::Yumrepo::IniConfig::Section.new('main', '/some/imaginary/file') sect.entries << ['distroverpkg', 'centos-release'] sect.entries << ['plugins', '1'] sect end let(:updates_section) do sect = Puppet::Provider::Yumrepo::IniConfig::Section.new('updates', '/some/imaginary/file') sect.entries << ['name', 'Some long description of the repo'] sect.entries << ['enabled', '1'] sect end before :each do allow(described_class).to receive(:virtual_inifile).and_return(virtual_inifile) end it 'ignores the main section' do expect(virtual_inifile).to receive(:each_section).and_yield(main_section).and_yield(updates_section) instances = described_class.instances expect(instances.size).to eq(1) expect(instances[0].name).to eq 'updates' end it 'creates provider instances for every non-main section that was found' do expect(virtual_inifile).to receive(:each_section).and_yield(main_section).and_yield(updates_section) sect = described_class.instances.first expect(sect.name).to eq 'updates' expect(sect.descr).to eq 'Some long description of the repo' expect(sect.enabled).to eq '1' end end describe 'retrieving a section from the inifile' do let(:collection) { instance_double('Puppet::Provider::Yumrepo::IniConfig::FileCollection') } let(:ini_section) { instance_double('Puppet::Provider::Yumrepo::IniConfig::Section', name: 'updates') } before(:each) do allow(described_class).to receive(:virtual_inifile).and_return(collection) allow(described_class).to receive(:reposdir).and_return ['/etc/yum.repos.d'] end describe 'and the requested section exists' do before(:each) do allow(collection).to receive(:each_section).and_yield(ini_section) end describe 'with no target specified' do it 'returns the existing section' do expect(described_class.section('updates', nil)).to eq ini_section end it "doesn't create a new section" do expect(collection).to receive(:add_section).never described_class.section('updates', nil) end end describe 'with a matching target' do target = '/etc/yum.repos.d/expected-path.repo' let(:ini_section) { instance_double('Puppet::Provider::Yumrepo::IniConfig::Section', name: 'updates', file: target) } it 'returns the existing section' do expect(described_class.section('updates', target)).to eq ini_section end it "doesn't create a new section" do expect(collection).to receive(:add_section).never described_class.section('updates', target) end end describe 'with a target that differs from an existing repo file' do target = '/etc/yum.repos.d/expected-path.repo' before(:each) do allow(collection).to receive(:add_section).with('updates', target).and_return(new_ini_section) allow(ini_section).to receive(:destroy=).with(true) allow(ini_section).to receive(:entries).and_return(['enabled', true]) end let(:ini_section) { instance_double('Puppet::Provider::Yumrepo::IniConfig::Section', name: 'updates', file: '/etc/yum.repos.d/updates.repo') } let(:new_ini_section) { Puppet::Provider::Yumrepo::IniConfig::Section.new('updates', target) } it 'creates a new section' do expect(collection).to receive(:add_section).with('updates', target) described_class.section('updates', target) end it 'marks old section for destruction' do expect(ini_section).to receive(:destroy=).with(true) described_class.section('updates', target) end it 'copies the old section' do expect(ini_section).to receive(:entries).and_return(['enabled', true]) section = described_class.section('updates', target) expect(section.entries).to eq(['enabled', true]) end end end describe "and the requested section doesn't exist" do before(:each) do allow(collection).to receive(:each_section) allow(described_class).to receive(:reposdir).and_return ['/etc/yum.repos.d', '/etc/alternate.repos.d'] end describe 'with no target specified' do let(:target) { nil } it 'creates a section in the preferred repodir' do expect(collection).to receive(:add_section).with('updates', '/etc/alternate.repos.d/updates.repo') described_class.section('updates', target) end it 'creates a section in yum.conf if no repodirs exist' do allow(described_class).to receive(:reposdir).and_return [] expect(collection).to receive(:add_section).with('updates', '/etc/yum.conf') described_class.section('updates', target) end end describe 'with relative path target specified' do let(:target) { 'custom_file.repo' } it 'creates a section in the preferred repodir' do expect(collection).to receive(:add_section).with('updates', "/etc/alternate.repos.d/#{target}") described_class.section('updates', target) end it 'creates a section in yum.conf if no repodirs exist' do allow(described_class).to receive(:reposdir).and_return [] expect(collection).to receive(:add_section).with('updates', '/etc/yum.conf') described_class.section('updates', target) end end describe 'with absolute path target specified' do describe 'path is not in valid repodir' do let(:target) { '/nonexistent_dir/custom_file.repo' } it 'creates a section in the preferred repodir' do expect(collection).to receive(:add_section).with('updates', '/etc/alternate.repos.d/custom_file.repo') described_class.section('updates', target) end it 'creates a section in yum.conf if no repodirs exist' do allow(described_class).to receive(:reposdir).and_return [] expect(collection).to receive(:add_section).with('updates', '/etc/yum.conf') described_class.section('updates', target) end end describe 'path is in valid repodir' do let(:target) { '/etc/yum.repos.d/custom_file.repo' } it 'creates a section in the preferred repodir' do expect(collection).to receive(:add_section).with('updates', target) described_class.section('updates', target) end it 'creates a section in yum.conf if no repodirs exist' do allow(described_class).to receive(:reposdir).and_return [] expect(collection).to receive(:add_section).with('updates', '/etc/yum.conf') described_class.section('updates', target) end end end end end describe 'repo_path' do subject(:repo_path) { described_class.repo_path(name, target) } before(:each) do allow(described_class).to receive(:reposdir).and_return ['/etc/yum.repos.d'] end let(:name) { 'updates' } describe 'target is nil' do let(:target) { nil } it 'uses repo name in default directory' do expect(repo_path).to eq('/etc/yum.repos.d/updates.repo') end end describe 'target is :absent' do let(:target) { :absent } it 'uses repo name in default directory' do expect(repo_path).to eq('/etc/yum.repos.d/updates.repo') end end describe 'target path is absolute' do describe 'in an invalid repodir' do describe 'with .repo suffix' do let(:target) { '/nonexistent_dir/custom_file.repo' } it 'uses target basename in default directory' do expect(repo_path).to eq('/etc/yum.repos.d/custom_file.repo') end end describe 'without .repo suffix' do let(:target) { '/nonexistent_dir/custom_file' } it 'uses target basename in default directory' do expect(repo_path).to eq('/etc/yum.repos.d/custom_file.repo') end end end describe 'in a valid repodir' do describe 'with .repo suffix' do let(:target) { '/etc/yum.repos.d/custom_file.repo' } it 'uses target' do expect(repo_path).to eq('/etc/yum.repos.d/custom_file.repo') end end describe 'without .repo suffix' do let(:target) { '/etc/yum.repos.d/custom_file' } it 'uses target' do expect(repo_path).to eq('/etc/yum.repos.d/custom_file.repo') end end end end describe 'target path is relative' do describe 'with .repo suffix' do let(:target) { 'custom_file.repo' } it 'uses target in default directory' do expect(repo_path).to eq('/etc/yum.repos.d/custom_file.repo') end end describe 'without .repo suffix' do let(:target) { 'custom_file' } it 'uses target in default directory' do expect(repo_path).to eq('/etc/yum.repos.d/custom_file.repo') end end end end describe 'setting and getting properties' do let(:type_instance) do Puppet::Type.type(:yumrepo).new( name: 'puppetlabs-products', ensure: :present, baseurl: 'http://yum.puppetlabs.com/el/6/products/$basearch', descr: 'Puppet Labs Products El 6 - $basearch', enabled: '1', gpgcheck: '1', gpgkey: 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs', ) end let(:provider) do described_class.new(type_instance) end let(:section) do instance_double('Puppet::Provider::Yumrepo::IniConfig::Section', name: 'puppetlabs-products') end before(:each) do type_instance.provider = provider allow(described_class).to receive(:reposdir).and_return ['/etc/yum.repos.d'] allow(described_class).to receive(:section).with('puppetlabs-products', '/etc/yum.repos.d/puppetlabs-products.repo').and_return(section) end describe 'methods used by ensurable' do it '#create sets the yumrepo properties on the according section' do expect(section).to receive(:[]=).with('baseurl', 'http://yum.puppetlabs.com/el/6/products/$basearch') expect(section).to receive(:[]=).with('name', 'Puppet Labs Products El 6 - $basearch') expect(section).to receive(:[]=).with('enabled', '1') expect(section).to receive(:[]=).with('gpgcheck', '1') expect(section).to receive(:[]=).with('gpgkey', 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs') provider.create end it '#exists? checks if the repo has been marked as present' do allow(described_class).to receive(:section).and_return(instance_double('Puppet::Provider::Yumrepo::IniConfig::Section', :[]= => nil)) provider.create expect(provider).to be_exist end it '#destroy deletes the associated ini file section' do expect(described_class).to receive(:section).and_return(section) expect(section).to receive(:destroy=).with(true) provider.destroy end end describe 'getting properties' do it "maps the 'descr' property to the 'name' INI property" do expect(section).to receive(:[]).with('name').and_return 'Some rather long description of the repository' expect(provider.descr).to eq 'Some rather long description of the repository' end it 'gets the property from the INI section' do expect(section).to receive(:[]).with('enabled').and_return '1' expect(provider.enabled).to eq '1' end it 'sets the property as :absent if the INI property is nil' do expect(section).to receive(:[]).with('exclude').and_return nil expect(provider.exclude).to eq :absent end end describe 'setting properties' do it "maps the 'descr' property to the 'name' INI property" do expect(section).to receive(:[]=).with('name', 'Some rather long description of the repository') provider.descr = 'Some rather long description of the repository' end it 'sets the property on the INI section' do expect(section).to receive(:[]=).with('enabled', '0') provider.enabled = '0' end it 'sets the section field to nil when the specified value is absent' do expect(section).to receive(:[]=).with('exclude', nil) provider.exclude = :absent end end end describe 'reposdir' do let(:defaults) { ['/etc/yum.repos.d', '/etc/yum/repos.d'] } before(:each) do allow(Puppet::FileSystem).to receive(:exist?).with('/etc/yum.repos.d').and_return(true) allow(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/repos.d').and_return(true) end it "returns the default directories if yum.conf doesn't contain a `reposdir` entry" do allow(described_class).to receive(:find_conf_value).with('reposdir', '/etc/yum.conf') expect(described_class.reposdir('/etc/yum.conf')).to eq(defaults) end it "includes the directory specified by the yum.conf 'reposdir' entry when the directory is present" do expect(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/extra.repos.d').and_return(true) expect(described_class).to receive(:find_conf_value).with('reposdir', '/etc/yum.conf').and_return '/etc/yum/extra.repos.d' expect(described_class.reposdir('/etc/yum.conf')).to include('/etc/yum/extra.repos.d') end it 'includes the directory if the value is split by whitespace' do expect(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/extra.repos.d').and_return(true) expect(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/misc.repos.d').and_return(true) expect(described_class).to receive(:find_conf_value).with('reposdir', '/etc/yum.conf').and_return '/etc/yum/extra.repos.d /etc/yum/misc.repos.d' expect(described_class.reposdir('/etc/yum.conf')).to include('/etc/yum/extra.repos.d', '/etc/yum/misc.repos.d') end it 'includes the directory if the value is split by new lines' do expect(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/extra.repos.d').and_return(true) expect(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/misc.repos.d').and_return(true) expect(described_class).to receive(:find_conf_value).with('reposdir', '/etc/yum.conf').and_return "/etc/yum/extra.repos.d\n/etc/yum/misc.repos.d" expect(described_class.reposdir('/etc/yum.conf')).to include('/etc/yum/extra.repos.d', '/etc/yum/misc.repos.d') end it "doesn't include the directory specified by the yum.conf 'reposdir' entry when the directory is absent" do expect(Puppet::FileSystem).to receive(:exist?).with('/etc/yum/extra.repos.d').and_return(false) expect(described_class).to receive(:find_conf_value).with('reposdir', '/etc/yum.conf').and_return '/etc/yum/extra.repos.d' expect(described_class.reposdir('/etc/yum.conf')).not_to include('/etc/yum/extra.repos.d') end it 'logs a warning and returns an empty array if none of the specified repo directories exist' do allow(Puppet::FileSystem).to receive(:exist?).and_return false allow(described_class).to receive(:find_conf_value).with('reposdir', '/etc/yum.conf') expect(Puppet).to receive(:debug).with('No yum directories were found on the local filesystem') expect(described_class.reposdir('/etc/yum.conf')).to be_empty end end describe 'looking up a conf value' do describe "and the file doesn't exist" do it 'returns nil' do allow(Puppet::FileSystem).to receive(:exist?).and_return false expect(described_class.find_conf_value('reposdir')).to be_nil end end describe 'and the file exists' do let(:pfile) { instance_double('Puppet::Provider::Yumrepo::IniConfig::PhysicalFile') } let(:sect) { instance_double('Puppet::Provider::Yumrepo::IniConfig::Section') } before(:each) do allow(Puppet::FileSystem).to receive(:exist?).with('/etc/yum.conf').and_return true allow(Puppet::Provider::Yumrepo::IniConfig::PhysicalFile).to receive(:new).with('/etc/yum.conf').and_return pfile allow(pfile).to receive(:read) end it 'creates a PhysicalFile to parse the given file' do expect(pfile).to receive(:get_section) described_class.find_conf_value('reposdir') end it "returns nil if the file exists but the 'main' section doesn't exist" do expect(pfile).to receive(:get_section).with('main') expect(described_class.find_conf_value('reposdir')).to be_nil end it "returns nil if the file exists but the INI property doesn't exist" do expect(pfile).to receive(:get_section).with('main').and_return sect expect(sect).to receive(:[]).with('reposdir') expect(described_class.find_conf_value('reposdir')).to be_nil end it 'returns the value if the value is defined in the PhysicalFile' do expect(pfile).to receive(:get_section).with('main').and_return sect expect(sect).to receive(:[]).with('reposdir').and_return '/etc/alternate.repos.d' expect(described_class.find_conf_value('reposdir')).to eq '/etc/alternate.repos.d' end end end describe 'resource application after prefetch' do let(:type_instance) do Puppet::Type.type(:yumrepo).new( name: 'puppetlabs-products', ensure: :present, baseurl: 'http://yum.puppetlabs.com/el/6/products/$basearch', descr: 'Puppet Labs Products El 6 - $basearch', enabled: '1', gpgcheck: '1', gpgkey: 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs', ) end let(:provider) do described_class.new(type_instance) end let(:yumrepo_dir) { tmpdir('yumrepo_integration_specs') } let(:yumrepo_conf_file) { tmpfile('yumrepo_conf_file', yumrepo_dir) } before :each do allow(described_class).to receive(:reposdir).and_return [yumrepo_dir] type_instance.provider = provider end it 'preserves repo file contents that were created after prefetch' do provider.class.prefetch({}) # we specifically want to create a file after prefetch has happened so that # none of the sections in the file exist in the prefetch cache repo_file = File.join(yumrepo_dir, 'puppetlabs-products.repo') contents = <<-HEREDOC [puppetlabs-products] name=created_by_package_after_prefetch enabled=1 failovermethod=priority gpgcheck=0 [additional_section] name=Extra Packages for Enterprise Linux 6 - $basearch - Debug #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 HEREDOC File.open(repo_file, 'wb') { |f| f.write(contents) } provider.create provider.flush expected_contents = <<-HEREDOC [puppetlabs-products] name=Puppet Labs Products El 6 - $basearch enabled=1 failovermethod=priority gpgcheck=1 baseurl=http://yum.puppetlabs.com/el/6/products/$basearch gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs [additional_section] name=Extra Packages for Enterprise Linux 6 - $basearch - Debug #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 HEREDOC expect(File.read(repo_file)).to eq(expected_contents) end it 'does not error becuase of repo files that have been removed from disk' do repo_file = File.join(yumrepo_dir, 'epel.repo') contents = <<-HEREDOC [epel] name=created_by_package_after_prefetch enabled=1 failovermethod=priority gpgcheck=0 HEREDOC File.open(repo_file, 'wb') { |f| f.write(contents) } provider.class.prefetch({}) File.delete(repo_file) provider.create provider.flush end end describe 'it redacts passwords' do before :each do yumrepo_dir = tmpdir('yumrepo_provider_specs') yumrepo_conf_file = tmpfile('yumrepo_conf_file', yumrepo_dir) allow(described_class).to receive(:reposdir).and_return [yumrepo_dir] allow(described_class).to receive(:repofiles).and_return [yumrepo_conf_file] end it 'redacts "password" on update' do apply_with_error_check(<<MANIFEST) yumrepo { 'puppetlabs': password => 'top secret' } MANIFEST transaction = apply_with_error_check(<<MANIFEST) yumrepo { 'puppetlabs': password => 'super classified' } MANIFEST status = transaction.report.resource_statuses['Yumrepo[puppetlabs]'] expect(status.events.first.message).to eq('changed [redacted] to [redacted]') end it 'redacts "proxy_password" on update' do apply_with_error_check(<<MANIFEST) yumrepo { 'puppetlabs': proxy_password => 'top secret' } MANIFEST transaction = apply_with_error_check(<<MANIFEST) yumrepo { 'puppetlabs': password => 'super classified' } MANIFEST status = transaction.report.resource_statuses['Yumrepo[puppetlabs]'] expect(status.events.first.message).to eq('changed [redacted] to [redacted]') end end end
修改文件时间
将文件时间修改为当前时间的前一年
删除文件