puppet 6.19.0-x64-mingw32 → 6.22.1-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CODEOWNERS +2 -16
- data/Gemfile +3 -1
- data/Gemfile.lock +50 -39
- data/ext/project_data.yaml +2 -2
- data/lib/puppet/application.rb +10 -6
- data/lib/puppet/application/agent.rb +1 -0
- data/lib/puppet/application/apply.rb +3 -2
- data/lib/puppet/application/device.rb +1 -0
- data/lib/puppet/application/filebucket.rb +2 -2
- data/lib/puppet/application/script.rb +1 -0
- data/lib/puppet/application/ssl.rb +11 -0
- data/lib/puppet/application_support.rb +7 -0
- data/lib/puppet/configurer.rb +28 -18
- data/lib/puppet/defaults.rb +46 -20
- data/lib/puppet/environments.rb +54 -55
- data/lib/puppet/face/config.rb +10 -0
- data/lib/puppet/face/epp.rb +12 -2
- data/lib/puppet/face/facts.rb +158 -0
- data/lib/puppet/ffi/posix.rb +10 -0
- data/lib/puppet/ffi/posix/constants.rb +14 -0
- data/lib/puppet/ffi/posix/functions.rb +24 -0
- data/lib/puppet/file_system/memory_file.rb +8 -1
- data/lib/puppet/file_system/windows.rb +2 -0
- data/lib/puppet/functions/epp.rb +1 -0
- data/lib/puppet/functions/inline_epp.rb +1 -0
- data/lib/puppet/functions/partition.rb +8 -0
- data/lib/puppet/indirector/fact_search.rb +60 -0
- data/lib/puppet/indirector/facts/facter.rb +24 -3
- data/lib/puppet/indirector/facts/json.rb +27 -0
- data/lib/puppet/indirector/facts/yaml.rb +3 -58
- data/lib/puppet/indirector/json.rb +5 -1
- data/lib/puppet/indirector/node/json.rb +8 -0
- data/lib/puppet/indirector/report/json.rb +34 -0
- data/lib/puppet/module_tool/applications/installer.rb +48 -2
- data/lib/puppet/module_tool/errors/shared.rb +17 -2
- data/lib/puppet/network/formats.rb +69 -1
- data/lib/puppet/network/http/factory.rb +4 -0
- data/lib/puppet/pal/pal_impl.rb +70 -17
- data/lib/puppet/parser/ast/leaf.rb +3 -2
- data/lib/puppet/parser/templatewrapper.rb +1 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
- data/lib/puppet/pops/model/ast_transformer.rb +1 -1
- data/lib/puppet/property/list.rb +1 -1
- data/lib/puppet/provider/group/groupadd.rb +13 -8
- data/lib/puppet/provider/package/apt.rb +34 -2
- data/lib/puppet/provider/package/aptitude.rb +6 -0
- data/lib/puppet/provider/package/dnfmodule.rb +1 -1
- data/lib/puppet/provider/service/debian.rb +2 -0
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/user/aix.rb +2 -2
- data/lib/puppet/provider/user/useradd.rb +62 -8
- data/lib/puppet/reference/configuration.rb +6 -5
- data/lib/puppet/settings.rb +43 -15
- data/lib/puppet/settings/alias_setting.rb +37 -0
- data/lib/puppet/settings/base_setting.rb +26 -2
- data/lib/puppet/settings/environment_conf.rb +1 -0
- data/lib/puppet/type/package.rb +3 -3
- data/lib/puppet/util/autoload.rb +1 -8
- data/lib/puppet/util/fact_dif.rb +81 -0
- data/lib/puppet/util/monkey_patches.rb +7 -0
- data/lib/puppet/util/posix.rb +54 -5
- data/lib/puppet/util/rubygems.rb +5 -1
- data/lib/puppet/util/windows/adsi.rb +46 -0
- data/lib/puppet/util/windows/api_types.rb +1 -1
- data/lib/puppet/util/windows/principal.rb +9 -2
- data/lib/puppet/util/windows/service.rb +1 -1
- data/lib/puppet/util/windows/sid.rb +4 -2
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +295 -219
- data/man/man5/puppet.conf.5 +15 -7
- data/man/man8/puppet-agent.8 +2 -2
- data/man/man8/puppet-apply.8 +2 -2
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +2 -2
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +90 -1
- data/man/man8/puppet-filebucket.8 +3 -3
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +4 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +4 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +2 -2
- data/man/man8/puppet-ssl.8 +5 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
- data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services_vendor_preset +9 -0
- data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
- data/spec/integration/application/agent_spec.rb +160 -3
- data/spec/integration/application/apply_spec.rb +19 -0
- data/spec/integration/application/plugin_spec.rb +1 -1
- data/spec/integration/defaults_spec.rb +0 -7
- data/spec/integration/environments/setting_hooks_spec.rb +1 -1
- data/spec/integration/http/client_spec.rb +12 -0
- data/spec/integration/indirector/direct_file_server_spec.rb +1 -3
- data/spec/integration/resource/type_collection_spec.rb +2 -6
- data/spec/integration/transaction_spec.rb +4 -9
- data/spec/integration/util/windows/adsi_spec.rb +21 -1
- data/spec/integration/util/windows/principal_spec.rb +21 -0
- data/spec/integration/util/windows/registry_spec.rb +6 -10
- data/spec/lib/puppet_spec/settings.rb +6 -1
- data/spec/spec_helper.rb +12 -5
- data/spec/unit/agent_spec.rb +8 -6
- data/spec/unit/application/agent_spec.rb +0 -1
- data/spec/unit/application/config_spec.rb +224 -4
- data/spec/unit/application/facts_spec.rb +482 -3
- data/spec/unit/application/filebucket_spec.rb +0 -2
- data/spec/unit/application/ssl_spec.rb +23 -0
- data/spec/unit/application_spec.rb +51 -9
- data/spec/unit/confine/feature_spec.rb +1 -1
- data/spec/unit/confine_spec.rb +8 -2
- data/spec/unit/defaults_spec.rb +36 -1
- data/spec/unit/environments_spec.rb +221 -68
- data/spec/unit/face/config_spec.rb +27 -32
- data/spec/unit/face/facts_spec.rb +4 -0
- data/spec/unit/face/node_spec.rb +0 -11
- data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
- data/spec/unit/file_serving/metadata_spec.rb +3 -3
- data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
- data/spec/unit/file_system_spec.rb +9 -0
- data/spec/unit/forge/module_release_spec.rb +2 -7
- data/spec/unit/functions/inline_epp_spec.rb +26 -1
- data/spec/unit/http/service/compiler_spec.rb +49 -0
- data/spec/unit/http/service_spec.rb +1 -1
- data/spec/unit/indirector/face_spec.rb +0 -1
- data/spec/unit/indirector/facts/facter_spec.rb +95 -1
- data/spec/unit/indirector/facts/json_spec.rb +255 -0
- data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
- data/spec/unit/indirector/indirection_spec.rb +8 -12
- data/spec/unit/indirector/key/file_spec.rb +0 -1
- data/spec/unit/indirector/node/json_spec.rb +33 -0
- data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
- data/spec/unit/indirector/report/yaml_spec.rb +72 -8
- data/spec/unit/indirector_spec.rb +2 -2
- data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
- data/spec/unit/network/authconfig_spec.rb +0 -3
- data/spec/unit/network/formats_spec.rb +41 -0
- data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
- data/spec/unit/network/http/factory_spec.rb +19 -0
- data/spec/unit/network/http/handler_spec.rb +0 -5
- data/spec/unit/parser/compiler_spec.rb +3 -19
- data/spec/unit/parser/resource_spec.rb +14 -8
- data/spec/unit/parser/templatewrapper_spec.rb +4 -3
- data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
- data/spec/unit/property_spec.rb +1 -0
- data/spec/unit/provider/group/groupadd_spec.rb +5 -2
- data/spec/unit/provider/nameservice_spec.rb +66 -65
- data/spec/unit/provider/package/apt_spec.rb +28 -23
- data/spec/unit/provider/package/aptitude_spec.rb +1 -1
- data/spec/unit/provider/package/base_spec.rb +6 -5
- data/spec/unit/provider/package/dnfmodule_spec.rb +10 -1
- data/spec/unit/provider/package/pacman_spec.rb +18 -12
- data/spec/unit/provider/package/pip_spec.rb +6 -11
- data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
- data/spec/unit/provider/service/systemd_spec.rb +11 -0
- data/spec/unit/provider/user/aix_spec.rb +5 -0
- data/spec/unit/provider/user/hpux_spec.rb +1 -1
- data/spec/unit/provider/user/pw_spec.rb +2 -0
- data/spec/unit/provider/user/useradd_spec.rb +71 -3
- data/spec/unit/provider_spec.rb +8 -10
- data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
- data/spec/unit/resource/capability_finder_spec.rb +6 -1
- data/spec/unit/resource/catalog_spec.rb +1 -1
- data/spec/unit/resource/type_spec.rb +1 -1
- data/spec/unit/resource_spec.rb +11 -10
- data/spec/unit/settings_spec.rb +543 -228
- data/spec/unit/ssl/base_spec.rb +0 -1
- data/spec/unit/ssl/host_spec.rb +0 -5
- data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
- data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
- data/spec/unit/transaction/event_manager_spec.rb +14 -11
- data/spec/unit/transaction_spec.rb +13 -4
- data/spec/unit/type/file/content_spec.rb +0 -1
- data/spec/unit/type/file/selinux_spec.rb +0 -2
- data/spec/unit/type/file_spec.rb +0 -6
- data/spec/unit/type/group_spec.rb +13 -6
- data/spec/unit/type/resources_spec.rb +7 -7
- data/spec/unit/type/service_spec.rb +1 -1
- data/spec/unit/type/tidy_spec.rb +0 -1
- data/spec/unit/type_spec.rb +2 -2
- data/spec/unit/util/at_fork_spec.rb +2 -2
- data/spec/unit/util/autoload_spec.rb +5 -1
- data/spec/unit/util/backups_spec.rb +1 -2
- data/spec/unit/util/execution_spec.rb +15 -11
- data/spec/unit/util/inifile_spec.rb +6 -14
- data/spec/unit/util/log_spec.rb +8 -7
- data/spec/unit/util/logging_spec.rb +3 -3
- data/spec/unit/util/posix_spec.rb +363 -15
- data/spec/unit/util/rubygems_spec.rb +2 -2
- data/spec/unit/util/selinux_spec.rb +76 -52
- data/spec/unit/util/storage_spec.rb +3 -1
- data/spec/unit/util/suidmanager_spec.rb +44 -41
- data/spec/unit/util/windows/sid_spec.rb +6 -0
- data/spec/unit/util_spec.rb +13 -6
- metadata +31 -16
- data/spec/integration/application/config_spec.rb +0 -74
- data/spec/lib/matchers/include.rb +0 -27
- data/spec/lib/matchers/include_spec.rb +0 -32
- data/spec/unit/face/catalog_spec.rb +0 -6
- data/spec/unit/face/module_spec.rb +0 -3
| @@ -1,5 +1,4 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 | 
            -
            require 'matchers/include'
         | 
| 3 2 |  | 
| 4 3 | 
             
            require 'puppet/indirector/file_content/file'
         | 
| 5 4 | 
             
            require 'puppet/indirector/file_metadata/file'
         | 
| @@ -30,7 +29,6 @@ end | |
| 30 29 |  | 
| 31 30 | 
             
            describe Puppet::Indirector::DirectFileServer, " when interacting with FileServing::Fileset and the model" do
         | 
| 32 31 | 
             
              include PuppetSpec::Files
         | 
| 33 | 
            -
              include Matchers::Include
         | 
| 34 32 |  | 
| 35 33 | 
             
              matcher :file_with_content do |name, content|
         | 
| 36 34 | 
             
                match do |actual|
         | 
| @@ -52,7 +50,7 @@ describe Puppet::Indirector::DirectFileServer, " when interacting with FileServi | |
| 52 50 | 
             
                terminus = Puppet::Indirector::FileContent::File.new
         | 
| 53 51 | 
             
                request = terminus.indirection.request(:search, Puppet::Util.path_to_uri(path).to_s, nil, :recurse => true)
         | 
| 54 52 |  | 
| 55 | 
            -
                expect(terminus.search(request)).to  | 
| 53 | 
            +
                expect(terminus.search(request)).to contain_exactly(
         | 
| 56 54 | 
             
                  file_with_content(File.join(path, "one"), "one content"),
         | 
| 57 55 | 
             
                  file_with_content(File.join(path, "two"), "two content"),
         | 
| 58 56 | 
             
                  directory_named(path))
         | 
| @@ -11,12 +11,8 @@ describe Puppet::Resource::TypeCollection do | |
| 11 11 | 
             
                  @dir = tmpfile("autoload_testing")
         | 
| 12 12 | 
             
                  FileUtils.mkdir_p @dir
         | 
| 13 13 |  | 
| 14 | 
            -
                  loader =  | 
| 15 | 
            -
                   | 
| 16 | 
            -
                  allow(loader).to receive(:set_entry)
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  loaders = Object.new
         | 
| 19 | 
            -
                  expect(loaders).to receive(:runtime3_type_loader).at_most(:once).and_return(loader)
         | 
| 14 | 
            +
                  loader = double('loader', load: nil, set_entry: nil)
         | 
| 15 | 
            +
                  loaders = double('loaders', runtime3_type_loader: loader)
         | 
| 20 16 | 
             
                  expect(Puppet::Pops::Loaders).to receive(:loaders).at_most(:once).and_return(loaders)
         | 
| 21 17 |  | 
| 22 18 | 
             
                  environment = Puppet::Node::Environment.create(:env, [@dir])
         | 
| @@ -61,7 +61,7 @@ describe Puppet::Transaction do | |
| 61 61 |  | 
| 62 62 | 
             
                transaction = Puppet::Transaction.new(catalog, nil, Puppet::Graph::SequentialPrioritizer.new)
         | 
| 63 63 |  | 
| 64 | 
            -
                expect(resource).not_to receive(: | 
| 64 | 
            +
                expect(resource).not_to receive(:retrieve)
         | 
| 65 65 |  | 
| 66 66 | 
             
                transaction.evaluate
         | 
| 67 67 | 
             
              end
         | 
| @@ -86,7 +86,7 @@ describe Puppet::Transaction do | |
| 86 86 |  | 
| 87 87 | 
             
                transaction = Puppet::Transaction.new(catalog, nil, Puppet::Graph::SequentialPrioritizer.new)
         | 
| 88 88 |  | 
| 89 | 
            -
                expect(resource).not_to receive(: | 
| 89 | 
            +
                expect(resource).not_to receive(:retrieve)
         | 
| 90 90 |  | 
| 91 91 | 
             
                transaction.evaluate
         | 
| 92 92 | 
             
              end
         | 
| @@ -315,16 +315,14 @@ describe Puppet::Transaction do | |
| 315 315 | 
             
                    file1 = tmpfile("file1")
         | 
| 316 316 | 
             
                    file2 = tmpfile("file2")
         | 
| 317 317 |  | 
| 318 | 
            +
                    expect(Puppet::FileSystem).to_not be_exist(file2)
         | 
| 319 | 
            +
             | 
| 318 320 | 
             
                    exec1 = Puppet::Type.type(:exec).new(
         | 
| 319 321 | 
             
                      :name        => "exec1",
         | 
| 320 322 | 
             
                      :path        => ENV["PATH"],
         | 
| 321 323 | 
             
                      :command     => touch(file1),
         | 
| 322 324 | 
             
                    )
         | 
| 323 325 |  | 
| 324 | 
            -
                    allow(exec1).to receive(:eval_generate).and_return(
         | 
| 325 | 
            -
                      [ Puppet::Type.type(:notify).new(:name => "eval1_notify") ]
         | 
| 326 | 
            -
                    )
         | 
| 327 | 
            -
             | 
| 328 326 | 
             
                    exec2 = Puppet::Type.type(:exec).new(
         | 
| 329 327 | 
             
                      :name        => "exec2",
         | 
| 330 328 | 
             
                      :path        => ENV["PATH"],
         | 
| @@ -332,9 +330,6 @@ describe Puppet::Transaction do | |
| 332 330 | 
             
                      :refreshonly => true,
         | 
| 333 331 | 
             
                      :subscribe   => exec1,
         | 
| 334 332 | 
             
                    )
         | 
| 335 | 
            -
                    allow(exec2).to receive(:eval_generate).and_return(
         | 
| 336 | 
            -
                      [ Puppet::Type.type(:notify).new(:name => "eval2_notify") ]
         | 
| 337 | 
            -
                    )
         | 
| 338 333 |  | 
| 339 334 | 
             
                    Puppet[:tags] = "exec"
         | 
| 340 335 | 
             
                    catalog = mk_catalog(exec1, exec2)
         | 
| @@ -55,6 +55,24 @@ describe Puppet::Util::Windows::ADSI::User, | |
| 55 55 | 
             
                  end
         | 
| 56 56 | 
             
                end
         | 
| 57 57 | 
             
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              describe '.current_user_name_with_format' do
         | 
| 60 | 
            +
                context 'when desired format is NameSamCompatible' do
         | 
| 61 | 
            +
                  it 'should get the same user name as the current_user_name method but fully qualified' do
         | 
| 62 | 
            +
                    user_name = Puppet::Util::Windows::ADSI::User.current_user_name
         | 
| 63 | 
            +
                    fully_qualified_user_name = Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    expect(fully_qualified_user_name).to match(/^.+\\#{user_name}$/)
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  it 'should have the same SID as with the current_user_name method' do
         | 
| 69 | 
            +
                    user_name = Puppet::Util::Windows::ADSI::User.current_user_name
         | 
| 70 | 
            +
                    fully_qualified_user_name = Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    expect(Puppet::Util::Windows::SID.name_to_sid(user_name)).to eq(Puppet::Util::Windows::SID.name_to_sid(fully_qualified_user_name))
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
              end
         | 
| 58 76 | 
             
            end
         | 
| 59 77 |  | 
| 60 78 | 
             
            describe Puppet::Util::Windows::ADSI::Group,
         | 
| @@ -157,7 +175,9 @@ describe Puppet::Util::Windows::ADSI::Group, | |
| 157 175 |  | 
| 158 176 | 
             
                  # touch the native_object member to have it lazily loaded, so COM objects can be stubbed
         | 
| 159 177 | 
             
                  admins.native_object
         | 
| 160 | 
            -
                   | 
| 178 | 
            +
                  without_partial_double_verification do
         | 
| 179 | 
            +
                    allow(admins.native_object).to receive(:Members).and_return(members)
         | 
| 180 | 
            +
                  end
         | 
| 161 181 |  | 
| 162 182 | 
             
                  # well-known NULL SID
         | 
| 163 183 | 
             
                  expect(admins.members[0].sid).to eq('S-1-0-0')
         | 
| @@ -7,6 +7,7 @@ describe Puppet::Util::Windows::SID::Principal, :if => Puppet::Util::Platform.wi | |
| 7 7 | 
             
              let (:system_bytes) { [1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0] }
         | 
| 8 8 | 
             
              let (:null_sid_bytes) { [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
         | 
| 9 9 | 
             
              let (:administrator_bytes) { [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] }
         | 
| 10 | 
            +
              let (:all_application_packages_bytes) { [1, 2, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 1, 0, 0, 0] }
         | 
| 10 11 | 
             
              let (:computer_sid) { Puppet::Util::Windows::SID.name_to_principal(Puppet::Util::Windows::ADSI.computer_name) }
         | 
| 11 12 | 
             
              # BUILTIN is localized on German Windows, but not French
         | 
| 12 13 | 
             
              # looking this up like this dilutes the values of the tests as we're comparing two mechanisms
         | 
| @@ -121,6 +122,26 @@ describe Puppet::Util::Windows::SID::Principal, :if => Puppet::Util::Platform.wi | |
| 121 122 | 
             
                  expect(principal.to_s).to eq(builtin_localized)
         | 
| 122 123 | 
             
                end
         | 
| 123 124 |  | 
| 125 | 
            +
                it "should always sanitize the account name first" do
         | 
| 126 | 
            +
                  expect(Puppet::Util::Windows::SID::Principal).to receive(:sanitize_account_name).with('NT AUTHORITY\\SYSTEM').and_call_original
         | 
| 127 | 
            +
                  Puppet::Util::Windows::SID::Principal.lookup_account_name('NT AUTHORITY\\SYSTEM')
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                it "should be able to create an instance from an account name prefixed by APPLICATION PACKAGE AUTHORITY" do
         | 
| 131 | 
            +
                  principal = Puppet::Util::Windows::SID::Principal.lookup_account_name('APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES')
         | 
| 132 | 
            +
                  expect(principal.account).to eq('ALL APPLICATION PACKAGES')
         | 
| 133 | 
            +
                  expect(principal.sid_bytes).to eq(all_application_packages_bytes)
         | 
| 134 | 
            +
                  expect(principal.sid).to eq('S-1-15-2-1')
         | 
| 135 | 
            +
                  expect(principal.domain).to eq('APPLICATION PACKAGE AUTHORITY')
         | 
| 136 | 
            +
                  expect(principal.domain_account).to eq('APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES')
         | 
| 137 | 
            +
                  expect(principal.account_type).to eq(:SidTypeWellKnownGroup)
         | 
| 138 | 
            +
                  expect(principal.to_s).to eq('APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES')
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                it "should fail without proper account name sanitization when it is prefixed by APPLICATION PACKAGE AUTHORITY" do
         | 
| 142 | 
            +
                  given_account_name = 'APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES'
         | 
| 143 | 
            +
                  expect { Puppet::Util::Windows::SID::Principal.lookup_account_name(nil, false, given_account_name) }.to raise_error(Puppet::Util::Windows::Error, /No mapping between account names and security IDs was done./)
         | 
| 144 | 
            +
                end
         | 
| 124 145 | 
             
              end
         | 
| 125 146 |  | 
| 126 147 | 
             
              describe ".lookup_account_sid" do
         | 
| @@ -146,16 +146,6 @@ describe Puppet::Util::Windows::Registry do | |
| 146 146 | 
             
                    utf_8_bytes = ENDASH_UTF_8 + TM_UTF_8
         | 
| 147 147 | 
             
                    utf_8_str = utf_8_bytes.pack('c*').force_encoding(Encoding::UTF_8)
         | 
| 148 148 |  | 
| 149 | 
            -
                    # this problematic Ruby codepath triggers a conversion of UTF-16LE to
         | 
| 150 | 
            -
                    # a local codepage which can totally break when that codepage has no
         | 
| 151 | 
            -
                    # conversion from the given UTF-16LE characters to local codepage
         | 
| 152 | 
            -
                    # a prime example is that IBM437 has no conversion from a Unicode en-dash
         | 
| 153 | 
            -
                    expect(Win32::Registry).not_to receive(:export_string)
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                    # also, expect that we're using our variants of keys / values, not Rubys
         | 
| 156 | 
            -
                    expect(Win32::Registry).not_to receive(:each_key)
         | 
| 157 | 
            -
                    expect(Win32::Registry).not_to receive(:each_value)
         | 
| 158 | 
            -
             | 
| 159 149 | 
             
                    hklm.create("#{puppet_key}\\#{subkey_name}", Win32::Registry::KEY_ALL_ACCESS | regsam) do |reg|
         | 
| 160 150 | 
             
                      reg.write("#{guid}", Win32::Registry::REG_SZ, utf_16_str)
         | 
| 161 151 |  | 
| @@ -273,6 +263,12 @@ describe Puppet::Util::Windows::Registry do | |
| 273 263 | 
             
                      type: Win32::Registry::REG_EXPAND_SZ,
         | 
| 274 264 | 
             
                      value: "\0\0\0reg expand string",
         | 
| 275 265 | 
             
                      expected_value: ""
         | 
| 266 | 
            +
                    },
         | 
| 267 | 
            +
                    {
         | 
| 268 | 
            +
                      name: 'REG_EXPAND_SZ_2',
         | 
| 269 | 
            +
                      type: Win32::Registry::REG_EXPAND_SZ,
         | 
| 270 | 
            +
                      value: "1\x002\x003\x004\x00\x00\x00\x90\xD8UoY".force_encoding("UTF-16LE"),
         | 
| 271 | 
            +
                      expected_value: "1234"
         | 
| 276 272 | 
             
                    }
         | 
| 277 273 | 
             
                  ].each do |pair|
         | 
| 278 274 | 
             
                    it 'reads up to the first wide null' do
         | 
| @@ -12,7 +12,12 @@ module PuppetSpec::Settings | |
| 12 12 | 
             
                :codedir      => { :type => :directory, :default => "test", :desc => "codedir" },
         | 
| 13 13 | 
             
                :vardir       => { :type => :directory, :default => "test", :desc => "vardir" },
         | 
| 14 14 | 
             
                :rundir       => { :type => :directory, :default => "test", :desc => "rundir" },
         | 
| 15 | 
            -
              }
         | 
| 15 | 
            +
              }.freeze
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              TEST_APP_DEFAULT_VALUES = TEST_APP_DEFAULT_DEFINITIONS.inject({}) do |memo, (key, value)|
         | 
| 18 | 
            +
                memo[key] = value[:default]
         | 
| 19 | 
            +
                memo
         | 
| 20 | 
            +
              end.freeze
         | 
| 16 21 |  | 
| 17 22 | 
             
              def set_puppet_conf(confdir, settings)
         | 
| 18 23 | 
             
                write_file(File.join(confdir, "puppet.conf"), settings)
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -84,10 +84,7 @@ RSpec.configure do |config| | |
| 84 84 | 
             
              config.filter_run_when_matching :focus
         | 
| 85 85 |  | 
| 86 86 | 
             
              config.mock_with :rspec do |mocks|
         | 
| 87 | 
            -
                 | 
| 88 | 
            -
                # need to go through and fix those tests first before it can be enabled
         | 
| 89 | 
            -
                # for real.
         | 
| 90 | 
            -
                mocks.verify_partial_doubles = false
         | 
| 87 | 
            +
                mocks.verify_partial_doubles = true
         | 
| 91 88 | 
             
              end
         | 
| 92 89 |  | 
| 93 90 | 
             
              tmpdir = Puppet::FileSystem.expand_path(Dir.mktmpdir("rspecrun"))
         | 
| @@ -163,10 +160,20 @@ RSpec.configure do |config| | |
| 163 160 | 
             
              PUPPET_FACTER_2_GCE_URL = %r{^http://metadata/computeMetadata/v1(beta1)?}.freeze
         | 
| 164 161 | 
             
              PUPPET_FACTER_3_GCE_URL = "http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=json".freeze
         | 
| 165 162 |  | 
| 163 | 
            +
              # Facter azure metadata endpoint
         | 
| 164 | 
            +
              PUPPET_FACTER_AZ_URL = "http://169.254.169.254/metadata/instance?api-version=2020-09-01"
         | 
| 165 | 
            +
             | 
| 166 | 
            +
              # Facter EC2 endpoint
         | 
| 167 | 
            +
              PUPPET_FACTER_EC2_METADATA_URL = 'http://169.254.169.254/latest/meta-data/'
         | 
| 168 | 
            +
              PUPPET_FACTER_EC2_USERDATA_URL = 'http://169.254.169.254/latest/user-data/'
         | 
| 169 | 
            +
             | 
| 166 170 | 
             
              config.around :each do |example|
         | 
| 167 | 
            -
                # Ignore requests from Facter  | 
| 171 | 
            +
                # Ignore requests from Facter to external services
         | 
| 168 172 | 
             
                stub_request(:get, PUPPET_FACTER_2_GCE_URL)
         | 
| 169 173 | 
             
                stub_request(:get, PUPPET_FACTER_3_GCE_URL)
         | 
| 174 | 
            +
                stub_request(:get, PUPPET_FACTER_AZ_URL)
         | 
| 175 | 
            +
                stub_request(:get, PUPPET_FACTER_EC2_METADATA_URL)
         | 
| 176 | 
            +
                stub_request(:get, PUPPET_FACTER_EC2_USERDATA_URL)
         | 
| 170 177 |  | 
| 171 178 | 
             
                # Enable VCR if the example is tagged with `:vcr` metadata.
         | 
| 172 179 | 
             
                if example.metadata[:vcr]
         | 
    
        data/spec/unit/agent_spec.rb
    CHANGED
    
    | @@ -3,9 +3,13 @@ require 'puppet/agent' | |
| 3 3 | 
             
            require 'puppet/configurer'
         | 
| 4 4 |  | 
| 5 5 | 
             
            class AgentTestClient
         | 
| 6 | 
            -
              def  | 
| 6 | 
            +
              def initialize(transaction_uuid = nil, job_id = nil)
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def run(client_args)
         | 
| 7 10 | 
             
                # no-op
         | 
| 8 11 | 
             
              end
         | 
| 12 | 
            +
             | 
| 9 13 | 
             
              def stop
         | 
| 10 14 | 
             
                # no-op
         | 
| 11 15 | 
             
              end
         | 
| @@ -51,11 +55,10 @@ describe Puppet::Agent do | |
| 51 55 |  | 
| 52 56 | 
             
              it "should create an instance of its client class and run it when asked to run" do
         | 
| 53 57 | 
             
                client = double('client')
         | 
| 54 | 
            -
                 | 
| 55 | 
            -
             | 
| 56 | 
            -
                expect(client).to receive(:run)
         | 
| 58 | 
            +
                allow(AgentTestClient).to receive(:new).with(nil, nil).and_return(client)
         | 
| 57 59 |  | 
| 58 60 | 
             
                allow(@agent).to receive(:disabled?).and_return(false)
         | 
| 61 | 
            +
                expect(client).to receive(:run)
         | 
| 59 62 | 
             
                @agent.run
         | 
| 60 63 | 
             
              end
         | 
| 61 64 |  | 
| @@ -92,7 +95,6 @@ describe Puppet::Agent do | |
| 92 95 |  | 
| 93 96 | 
             
              describe "when being run" do
         | 
| 94 97 | 
             
                before do
         | 
| 95 | 
            -
                  allow(AgentTestClient).to receive(:lockfile_path).and_return("/my/lock")
         | 
| 96 98 | 
             
                  allow(@agent).to receive(:disabled?).and_return(false)
         | 
| 97 99 | 
             
                end
         | 
| 98 100 |  | 
| @@ -188,7 +190,7 @@ describe Puppet::Agent do | |
| 188 190 | 
             
                    allow(lockfile).to receive(:lock).and_return(false)
         | 
| 189 191 | 
             
                  end
         | 
| 190 192 |  | 
| 191 | 
            -
                  it "should notify that a run is already in  | 
| 193 | 
            +
                  it "should notify that a run is already in progress" do
         | 
| 192 194 | 
             
                    client = AgentTestClient.new
         | 
| 193 195 | 
             
                    expect(AgentTestClient).to receive(:new).and_return(client)
         | 
| 194 196 | 
             
                    expect(Puppet).to receive(:notice).with(/Run of .* already in progress; skipping .* exists/)
         | 
| @@ -202,7 +202,6 @@ describe Puppet::Application::Agent do | |
| 202 202 | 
             
                  allow(Puppet::Resource::Catalog.indirection).to receive(:terminus_class=)
         | 
| 203 203 | 
             
                  allow(Puppet::Resource::Catalog.indirection).to receive(:cache_class=)
         | 
| 204 204 | 
             
                  allow(Puppet::Node::Facts.indirection).to receive(:terminus_class=)
         | 
| 205 | 
            -
                  allow(Puppet).to receive(:settraps)
         | 
| 206 205 | 
             
                end
         | 
| 207 206 |  | 
| 208 207 | 
             
                it "should not run with extra arguments" do
         | 
| @@ -1,12 +1,232 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 1 2 | 
             
            require 'spec_helper'
         | 
| 2 3 | 
             
            require 'puppet/application/config'
         | 
| 3 4 |  | 
| 4 5 | 
             
            describe Puppet::Application::Config do
         | 
| 5 | 
            -
               | 
| 6 | 
            -
             | 
| 6 | 
            +
              include PuppetSpec::Files
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              # different UTF-8 widths
         | 
| 9 | 
            +
              # 1-byte A
         | 
| 10 | 
            +
              # 2-byte ۿ - http://www.fileformat.info/info/unicode/char/06ff/index.htm - 0xDB 0xBF / 219 191
         | 
| 11 | 
            +
              # 3-byte ᚠ - http://www.fileformat.info/info/unicode/char/16A0/index.htm - 0xE1 0x9A 0xA0 / 225 154 160
         | 
| 12 | 
            +
              # 4-byte 𠜎 - http://www.fileformat.info/info/unicode/char/2070E/index.htm - 0xF0 0xA0 0x9C 0x8E / 240 160 156 142
         | 
| 13 | 
            +
              MIXED_UTF8 = "A\u06FF\u16A0\u{2070E}" # Aۿᚠ𠜎
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              let(:app) { Puppet::Application[:config] }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              before :each do
         | 
| 18 | 
            +
                Puppet[:config] = tmpfile('config')
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def initialize_app(args)
         | 
| 22 | 
            +
                app.command_line.args = args
         | 
| 23 | 
            +
                # ensure global defaults are initialized prior to app defaults
         | 
| 24 | 
            +
                Puppet.initialize_settings(args)
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def read_utf8(path)
         | 
| 28 | 
            +
                File.read(path, :encoding => 'UTF-8')
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              def write_utf8(path, content)
         | 
| 32 | 
            +
                File.write(path, content, 0, :encoding => 'UTF-8')
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              context "when printing" do
         | 
| 36 | 
            +
                it "prints a value" do
         | 
| 37 | 
            +
                  initialize_app(%w[print certname])
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  expect {
         | 
| 40 | 
            +
                    app.run
         | 
| 41 | 
            +
                  }.to exit_with(0)
         | 
| 42 | 
            +
                   .and output(a_string_matching(Puppet[:certname])).to_stdout
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                it "prints a value from a section" do
         | 
| 46 | 
            +
                  File.write(Puppet[:config], <<~END)
         | 
| 47 | 
            +
                    [main]
         | 
| 48 | 
            +
                    external_nodes=none
         | 
| 49 | 
            +
                    [server]
         | 
| 50 | 
            +
                    external_nodes=exec
         | 
| 51 | 
            +
                  END
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  initialize_app(%w[print external_nodes --section server])
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  expect {
         | 
| 56 | 
            +
                    app.run
         | 
| 57 | 
            +
                  }.to exit_with(0)
         | 
| 58 | 
            +
                   .and output(a_string_matching('exec')).to_stdout
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                it "doesn't require the environment to exist" do
         | 
| 62 | 
            +
                  initialize_app(%w[print certname --environment doesntexist])
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  expect {
         | 
| 65 | 
            +
                    app.run
         | 
| 66 | 
            +
                  }.to exit_with(0)
         | 
| 67 | 
            +
                   .and output(a_string_matching(Puppet[:certname])).to_stdout
         | 
| 68 | 
            +
                end
         | 
| 7 69 | 
             
              end
         | 
| 8 70 |  | 
| 9 | 
            -
               | 
| 10 | 
            -
                 | 
| 71 | 
            +
              context "when setting" do
         | 
| 72 | 
            +
                it "sets a value in its config file" do
         | 
| 73 | 
            +
                  initialize_app(%w[set certname www.example.com])
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  expect {
         | 
| 76 | 
            +
                    app.run
         | 
| 77 | 
            +
                  }.to exit_with(0)
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  expect(File.read(Puppet[:config])).to eq("[main]\ncertname = www.example.com\n")
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                it "sets a value in the server section" do
         | 
| 83 | 
            +
                  initialize_app(%w[set external_nodes exec --section server])
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  expect {
         | 
| 86 | 
            +
                    app.run
         | 
| 87 | 
            +
                  }.to exit_with(0)
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  expect(File.read(Puppet[:config])).to eq("[server]\nexternal_nodes = exec\n")
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                {
         | 
| 93 | 
            +
                  %w[certname WWW.EXAMPLE.COM] => /Certificate names must be lower case/,
         | 
| 94 | 
            +
                  %w[log_level all] => /Invalid loglevel all/,
         | 
| 95 | 
            +
                  %w[disable_warnings true] => /Cannot disable unrecognized warning types 'true'/,
         | 
| 96 | 
            +
                  %w[strict on] => /Invalid value 'on' for parameter strict/,
         | 
| 97 | 
            +
                  %w[digest_algorithm rot13] => /Invalid value 'rot13' for parameter digest_algorithm/,
         | 
| 98 | 
            +
                  %w[http_proxy_password a#b] => /Passwords set in the http_proxy_password setting must be valid as part of a URL/,
         | 
| 99 | 
            +
                }.each_pair do |args, message|
         | 
| 100 | 
            +
                  it "rejects #{args.join(' ')}" do
         | 
| 101 | 
            +
                    initialize_app(['set', *args])
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    expect {
         | 
| 104 | 
            +
                      app.run
         | 
| 105 | 
            +
                    }.to exit_with(1)
         | 
| 106 | 
            +
                     .and output(message).to_stderr
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                it 'sets unknown settings' do
         | 
| 111 | 
            +
                  initialize_app(['set', 'notarealsetting', 'true'])
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  expect {
         | 
| 114 | 
            +
                    app.run
         | 
| 115 | 
            +
                  }.to exit_with(0)
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  expect(File.read(Puppet[:config])).to eq("[main]\nnotarealsetting = true\n")
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              context "when deleting" do
         | 
| 122 | 
            +
                it "deletes a value" do
         | 
| 123 | 
            +
                  initialize_app(%w[delete external_nodes])
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  File.write(Puppet[:config], <<~END)
         | 
| 126 | 
            +
                    [main]
         | 
| 127 | 
            +
                    external_nodes=none
         | 
| 128 | 
            +
                  END
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                  expect {
         | 
| 131 | 
            +
                    app.run
         | 
| 132 | 
            +
                  }.to exit_with(0)
         | 
| 133 | 
            +
                   .and output(/Deleted setting from 'main': 'external_nodes=none'/).to_stdout
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  expect(File.read(Puppet[:config])).to eq("[main]\n")
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                it "warns when deleting a value that isn't set" do
         | 
| 139 | 
            +
                  initialize_app(%w[delete external_nodes])
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                  File.write(Puppet[:config], "")
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                  expect {
         | 
| 144 | 
            +
                    app.run
         | 
| 145 | 
            +
                  }.to exit_with(0)
         | 
| 146 | 
            +
                   .and output(a_string_matching("Warning: No setting found in configuration file for section 'main' setting name 'external_nodes'")).to_stderr
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  expect(File.read(Puppet[:config])).to eq("")
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                it "deletes a value from main" do
         | 
| 152 | 
            +
                  initialize_app(%w[delete external_nodes])
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                  File.write(Puppet[:config], <<~END)
         | 
| 155 | 
            +
                    [main]
         | 
| 156 | 
            +
                    external_nodes=none
         | 
| 157 | 
            +
                  END
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                  expect {
         | 
| 160 | 
            +
                    app.run
         | 
| 161 | 
            +
                  }.to exit_with(0)
         | 
| 162 | 
            +
                   .and output(/Deleted setting from 'main': 'external_nodes=none'/).to_stdout
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                  expect(File.read(Puppet[:config])).to eq("[main]\n")
         | 
| 165 | 
            +
                end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                it "deletes a value from main a section" do
         | 
| 168 | 
            +
                  initialize_app(%w[delete external_nodes --section server])
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                  File.write(Puppet[:config], <<~END)
         | 
| 171 | 
            +
                    [main]
         | 
| 172 | 
            +
                    external_nodes=none
         | 
| 173 | 
            +
                    [server]
         | 
| 174 | 
            +
                    external_nodes=exec
         | 
| 175 | 
            +
                  END
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  expect {
         | 
| 178 | 
            +
                    app.run
         | 
| 179 | 
            +
                  }.to exit_with(0)
         | 
| 180 | 
            +
                   .and output(/Deleted setting from 'server': 'external_nodes'/).to_stdout
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                  expect(File.read(Puppet[:config])).to eq("[main]\nexternal_nodes=none\n[server]\n")
         | 
| 183 | 
            +
                end
         | 
| 184 | 
            +
              end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              context "when managing UTF-8 values" do
         | 
| 187 | 
            +
                it "reads a UTF-8 value" do
         | 
| 188 | 
            +
                  write_utf8(Puppet[:config], <<~EOF)
         | 
| 189 | 
            +
                    [main]
         | 
| 190 | 
            +
                    tags=#{MIXED_UTF8}
         | 
| 191 | 
            +
                  EOF
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                  initialize_app(%w[print tags])
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                  expect {
         | 
| 196 | 
            +
                    app.run
         | 
| 197 | 
            +
                  }.to exit_with(0)
         | 
| 198 | 
            +
                   .and output("#{MIXED_UTF8}\n").to_stdout
         | 
| 199 | 
            +
                end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                it "sets a UTF-8 value" do
         | 
| 202 | 
            +
                  initialize_app(['set', 'tags', MIXED_UTF8])
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                  expect {
         | 
| 205 | 
            +
                    app.run
         | 
| 206 | 
            +
                  }.to exit_with(0)
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  expect(read_utf8(Puppet[:config])).to eq(<<~EOF)
         | 
| 209 | 
            +
                    [main]
         | 
| 210 | 
            +
                    tags = #{MIXED_UTF8}
         | 
| 211 | 
            +
                  EOF
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                it "deletes a UTF-8 value" do
         | 
| 215 | 
            +
                  initialize_app(%w[delete tags])
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                  write_utf8(Puppet[:config], <<~EOF)
         | 
| 218 | 
            +
                    [main]
         | 
| 219 | 
            +
                    tags=#{MIXED_UTF8}
         | 
| 220 | 
            +
                  EOF
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                  expect {
         | 
| 223 | 
            +
                    app.run
         | 
| 224 | 
            +
                  }.to exit_with(0)
         | 
| 225 | 
            +
                   .and output(/Deleted setting from 'main': 'tags=#{MIXED_UTF8}'/).to_stdout
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                  expect(read_utf8(Puppet[:config])).to eq(<<~EOF)
         | 
| 228 | 
            +
                    [main]
         | 
| 229 | 
            +
                  EOF
         | 
| 230 | 
            +
                end
         | 
| 11 231 | 
             
              end
         | 
| 12 232 | 
             
            end
         |