puppet 3.2.4 → 3.3.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/COMMITTERS.md +101 -42
- data/Gemfile +15 -4
- data/README.md +5 -1
- data/README_DEVELOPER.md +117 -54
- data/Rakefile +4 -0
- data/ext/build_defaults.yaml +3 -2
- data/ext/debian/puppet-common.manpages +33 -1
- data/ext/gentoo/init.d/puppet +1 -1
- data/ext/gentoo/init.d/puppetmaster +1 -1
- data/ext/redhat/puppet.spec.erb +0 -1
- data/install.rb +2 -1
- data/lib/hiera/backend/puppet_backend.rb +1 -1
- data/lib/puppet/application.rb +10 -9
- data/lib/puppet/application/agent.rb +87 -93
- data/lib/puppet/application/apply.rb +0 -2
- data/lib/puppet/application/device.rb +3 -3
- data/lib/puppet/application/kick.rb +2 -2
- data/lib/puppet/application/master.rb +41 -19
- data/lib/puppet/application/queue.rb +5 -3
- data/lib/puppet/bindings.rb +147 -0
- data/lib/puppet/configurer.rb +25 -15
- data/lib/puppet/configurer/fact_handler.rb +2 -9
- data/lib/puppet/daemon.rb +44 -33
- data/lib/puppet/defaults.rb +57 -26
- data/lib/puppet/error.rb +1 -1
- data/lib/puppet/external/dot.rb +2 -2
- data/lib/puppet/external/nagios/base.rb +1 -6
- data/lib/puppet/external/pson/common.rb +2 -2
- data/lib/puppet/external/pson/pure/generator.rb +2 -2
- data/lib/puppet/external/pson/pure/parser.rb +1 -1
- data/lib/puppet/face/ca.rb +1 -1
- data/lib/puppet/face/config.rb +1 -1
- data/lib/puppet/face/help.rb +2 -2
- data/lib/puppet/face/module/list.rb +2 -2
- data/lib/puppet/feature/rails.rb +1 -1
- data/lib/puppet/file_bucket/dipper.rb +0 -1
- data/lib/puppet/file_serving/base.rb +1 -1
- data/lib/puppet/file_serving/configuration/parser.rb +20 -14
- data/lib/puppet/forge.rb +0 -32
- data/lib/puppet/forge/cache.rb +1 -1
- data/lib/puppet/forge/errors.rb +3 -3
- data/lib/puppet/forge/repository.rb +7 -42
- data/lib/puppet/graph.rb +11 -0
- data/lib/puppet/graph/key.rb +26 -0
- data/lib/puppet/graph/prioritizer.rb +29 -0
- data/lib/puppet/graph/random_prioritizer.rb +16 -0
- data/lib/puppet/{rb_tree_map.rb → graph/rb_tree_map.rb} +3 -3
- data/lib/puppet/graph/relationship_graph.rb +246 -0
- data/lib/puppet/graph/sequential_prioritizer.rb +31 -0
- data/lib/puppet/{simple_graph.rb → graph/simple_graph.rb} +22 -3
- data/lib/puppet/graph/title_hash_prioritizer.rb +16 -0
- data/lib/puppet/indirector.rb +2 -2
- data/lib/puppet/indirector/catalog/compiler.rb +10 -7
- data/lib/puppet/indirector/catalog/static_compiler.rb +50 -0
- data/lib/puppet/indirector/certificate/rest.rb +1 -1
- data/lib/puppet/indirector/exec.rb +1 -1
- data/lib/puppet/indirector/facts/facter.rb +2 -2
- data/lib/puppet/indirector/facts/inventory_active_record.rb +0 -1
- data/lib/puppet/indirector/facts/network_device.rb +1 -1
- data/lib/puppet/indirector/file_bucket_file/file.rb +0 -1
- data/lib/puppet/indirector/indirection.rb +2 -2
- data/lib/puppet/indirector/memory.rb +9 -0
- data/lib/puppet/indirector/node/ldap.rb +2 -4
- data/lib/puppet/indirector/report/processor.rb +1 -2
- data/lib/puppet/indirector/report/rest.rb +1 -1
- data/lib/puppet/indirector/request.rb +32 -10
- data/lib/puppet/indirector/resource/rest.rb +1 -1
- data/lib/puppet/indirector/resource_type/parser.rb +31 -12
- data/lib/puppet/interface.rb +1 -1
- data/lib/puppet/interface/documentation.rb +7 -11
- data/lib/puppet/interface/option.rb +1 -1
- data/lib/puppet/interface/option_builder.rb +1 -1
- data/lib/puppet/metatype/manager.rb +2 -2
- data/lib/puppet/module.rb +7 -1
- data/lib/puppet/module_tool.rb +1 -1
- data/lib/puppet/module_tool/applications/application.rb +10 -0
- data/lib/puppet/module_tool/applications/installer.rb +6 -3
- data/lib/puppet/module_tool/dependency.rb +2 -0
- data/lib/puppet/module_tool/errors/upgrader.rb +1 -1
- data/lib/puppet/module_tool/metadata.rb +25 -13
- data/lib/puppet/module_tool/modulefile.rb +7 -7
- data/lib/puppet/module_tool/shared_behaviors.rb +4 -2
- data/lib/puppet/module_tool/skeleton.rb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/manifests/init.pp.erb +5 -5
- data/lib/puppet/module_tool/skeleton/templates/generator/tests/init.pp.erb +5 -4
- data/lib/puppet/network/auth_config_parser.rb +3 -0
- data/lib/puppet/network/authconfig.rb +0 -1
- data/lib/puppet/network/authorization.rb +1 -1
- data/lib/puppet/network/authstore.rb +2 -2
- data/lib/puppet/network/format_handler.rb +25 -114
- data/lib/puppet/network/format_support.rb +106 -0
- data/lib/puppet/network/formats.rb +10 -4
- data/lib/puppet/network/http/compression.rb +1 -1
- data/lib/puppet/network/http/connection.rb +76 -32
- data/lib/puppet/network/http/handler.rb +122 -61
- data/lib/puppet/network/http/rack/rest.rb +1 -1
- data/lib/puppet/network/http/webrick/rest.rb +9 -3
- data/lib/puppet/network/http_pool.rb +2 -2
- data/lib/puppet/network/resolver.rb +1 -0
- data/lib/puppet/network/server.rb +5 -81
- data/lib/puppet/node/environment.rb +256 -13
- data/lib/puppet/node/facts.rb +28 -2
- data/lib/puppet/parameter.rb +27 -18
- data/lib/puppet/parameter/boolean.rb +20 -0
- data/lib/puppet/parameter/path.rb +1 -1
- data/lib/puppet/parameter/value.rb +1 -1
- data/lib/puppet/parameter/value_collection.rb +1 -1
- data/lib/puppet/parser/ast/arithmetic_operator.rb +8 -0
- data/lib/puppet/parser/ast/casestatement.rb +0 -3
- data/lib/puppet/parser/ast/lambda.rb +25 -6
- data/lib/puppet/parser/ast/leaf.rb +10 -3
- data/lib/puppet/parser/ast/nop.rb +1 -1
- data/lib/puppet/parser/ast/resource_override.rb +0 -2
- data/lib/puppet/parser/compiler.rb +92 -34
- data/lib/puppet/parser/files.rb +0 -5
- data/lib/puppet/parser/functions/create_resources.rb +23 -46
- data/lib/puppet/parser/functions/each.rb +0 -2
- data/lib/puppet/parser/functions/extlookup.rb +2 -2
- data/lib/puppet/parser/functions/foreach.rb +0 -2
- data/lib/puppet/parser/functions/hiera_include.rb +1 -1
- data/lib/puppet/parser/functions/lookup.rb +44 -0
- data/lib/puppet/parser/functions/slice.rb +1 -1
- data/lib/puppet/parser/grammar.ra +0 -1
- data/lib/puppet/parser/lexer.rb +0 -1
- data/lib/puppet/parser/parser.rb +0 -1
- data/lib/puppet/parser/parser_factory.rb +3 -2
- data/lib/puppet/parser/parser_support.rb +1 -1
- data/lib/puppet/parser/relationship.rb +1 -1
- data/lib/puppet/parser/scope.rb +49 -24
- data/lib/puppet/parser/type_loader.rb +13 -18
- data/lib/puppet/pops.rb +45 -0
- data/lib/puppet/pops/adaptable.rb +2 -2
- data/lib/puppet/pops/adapters.rb +4 -0
- data/lib/puppet/pops/binder/binder.rb +421 -0
- data/lib/puppet/pops/binder/binder_issues.rb +142 -0
- data/lib/puppet/pops/binder/bindings_checker.rb +217 -0
- data/lib/puppet/pops/binder/bindings_composer.rb +241 -0
- data/lib/puppet/pops/binder/bindings_factory.rb +847 -0
- data/lib/puppet/pops/binder/bindings_label_provider.rb +46 -0
- data/lib/puppet/pops/binder/bindings_loader.rb +79 -0
- data/lib/puppet/pops/binder/bindings_model.rb +215 -0
- data/lib/puppet/pops/binder/bindings_model_dumper.rb +205 -0
- data/lib/puppet/pops/binder/bindings_validator_factory.rb +28 -0
- data/lib/puppet/pops/binder/config/binder_config.rb +139 -0
- data/lib/puppet/pops/binder/config/binder_config_checker.rb +183 -0
- data/lib/puppet/pops/binder/config/diagnostic_producer.rb +32 -0
- data/lib/puppet/pops/binder/config/issues.rb +106 -0
- data/lib/puppet/pops/binder/hiera2.rb +10 -0
- data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +148 -0
- data/lib/puppet/pops/binder/hiera2/config.rb +69 -0
- data/lib/puppet/pops/binder/hiera2/config_checker.rb +68 -0
- data/lib/puppet/pops/binder/hiera2/diagnostic_producer.rb +36 -0
- data/lib/puppet/pops/binder/hiera2/issues.rb +67 -0
- data/lib/puppet/pops/binder/hiera2/json_backend.rb +18 -0
- data/lib/puppet/pops/binder/hiera2/yaml_backend.rb +21 -0
- data/lib/puppet/pops/binder/injector.rb +688 -0
- data/lib/puppet/pops/binder/injector_entry.rb +53 -0
- data/lib/puppet/pops/binder/key_factory.rb +61 -0
- data/lib/puppet/pops/binder/producers.rb +829 -0
- data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +67 -0
- data/lib/puppet/pops/binder/scheme_handler/confdir_scheme.rb +34 -0
- data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +92 -0
- data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +84 -0
- data/lib/puppet/pops/binder/scheme_handler/symbolic_scheme.rb +54 -0
- data/lib/puppet/pops/binder/system_bindings.rb +72 -0
- data/lib/puppet/pops/issue_reporter.rb +75 -0
- data/lib/puppet/pops/issues.rb +9 -5
- data/lib/puppet/pops/model/ast_transformer.rb +4 -4
- data/lib/puppet/pops/model/ast_tree_dumper.rb +1 -1
- data/lib/puppet/pops/model/factory.rb +25 -13
- data/lib/puppet/pops/model/model.rb +1 -1
- data/lib/puppet/pops/model/tree_dumper.rb +2 -2
- data/lib/puppet/pops/parser/egrammar.ra +0 -1
- data/lib/puppet/pops/parser/eparser.rb +1 -2
- data/lib/puppet/pops/parser/evaluating_parser.rb +162 -0
- data/lib/puppet/pops/parser/lexer.rb +8 -6
- data/lib/puppet/pops/types/class_loader.rb +118 -0
- data/lib/puppet/pops/types/type_calculator.rb +557 -0
- data/lib/puppet/pops/types/type_factory.rb +147 -0
- data/lib/puppet/pops/types/type_parser.rb +117 -0
- data/lib/puppet/pops/types/types.rb +132 -0
- data/lib/puppet/pops/validation.rb +146 -17
- data/lib/puppet/pops/validation/checker3_1.rb +1 -1
- data/lib/puppet/pops/validation/validator_factory_3_1.rb +6 -16
- data/lib/puppet/property.rb +3 -3
- data/lib/puppet/property/keyvalue.rb +1 -1
- data/lib/puppet/provider.rb +2 -2
- data/lib/puppet/provider/aixobject.rb +19 -21
- data/lib/puppet/provider/augeas/augeas.rb +3 -1
- data/lib/puppet/provider/command.rb +2 -2
- data/lib/puppet/provider/group/aix.rb +1 -1
- data/lib/puppet/provider/group/ldap.rb +1 -1
- data/lib/puppet/provider/macauthorization/macauthorization.rb +1 -1
- data/lib/puppet/provider/mailalias/aliases.rb +3 -8
- data/lib/puppet/provider/mcx/mcxcontent.rb +7 -1
- data/lib/puppet/provider/mount.rb +8 -3
- data/lib/puppet/provider/nameservice.rb +1 -1
- data/lib/puppet/provider/nameservice/directoryservice.rb +5 -5
- data/lib/puppet/provider/package/appdmg.rb +1 -1
- data/lib/puppet/provider/package/apt.rb +0 -1
- data/lib/puppet/provider/package/dpkg.rb +86 -32
- data/lib/puppet/provider/package/fink.rb +0 -2
- data/lib/puppet/provider/package/freebsd.rb +0 -2
- data/lib/puppet/provider/package/openbsd.rb +57 -10
- data/lib/puppet/provider/package/opkg.rb +0 -1
- data/lib/puppet/provider/package/pacman.rb +0 -1
- data/lib/puppet/provider/package/pip.rb +1 -1
- data/lib/puppet/provider/package/pkgdmg.rb +17 -6
- data/lib/puppet/provider/package/pkgutil.rb +1 -1
- data/lib/puppet/provider/package/portage.rb +9 -1
- data/lib/puppet/provider/package/ports.rb +2 -2
- data/lib/puppet/provider/package/rpm.rb +29 -12
- data/lib/puppet/provider/package/rug.rb +1 -1
- data/lib/puppet/provider/package/urpmi.rb +11 -15
- data/lib/puppet/provider/package/windows/exe_package.rb +1 -1
- data/lib/puppet/provider/package/windows/package.rb +1 -26
- data/lib/puppet/provider/package/yum.rb +1 -1
- data/lib/puppet/provider/package/zypper.rb +22 -3
- data/lib/puppet/provider/parsedfile.rb +1 -12
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +1 -1
- data/lib/puppet/provider/service/base.rb +1 -1
- data/lib/puppet/provider/service/daemontools.rb +3 -3
- data/lib/puppet/provider/service/debian.rb +1 -1
- data/lib/puppet/provider/service/init.rb +14 -20
- data/lib/puppet/provider/service/openrc.rb +3 -1
- data/lib/puppet/provider/service/redhat.rb +5 -8
- data/lib/puppet/provider/service/runit.rb +3 -2
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
- data/lib/puppet/provider/sshkey/parsed.rb +0 -2
- data/lib/puppet/provider/user/aix.rb +25 -12
- data/lib/puppet/provider/user/directoryservice.rb +4 -7
- data/lib/puppet/provider/user/ldap.rb +0 -1
- data/lib/puppet/provider/user/user_role_add.rb +2 -0
- data/lib/puppet/provider/user/useradd.rb +1 -1
- data/lib/puppet/provider/zone/solaris.rb +1 -2
- data/lib/puppet/reference/metaparameter.rb +1 -1
- data/lib/puppet/reference/type.rb +1 -1
- data/lib/puppet/reports/rrdgraph.rb +1 -1
- data/lib/puppet/reports/tagmail.rb +1 -1
- data/lib/puppet/resource.rb +16 -4
- data/lib/puppet/resource/catalog.rb +111 -173
- data/lib/puppet/resource/status.rb +42 -3
- data/lib/puppet/resource/type.rb +33 -46
- data/lib/puppet/resource/type_collection.rb +19 -15
- data/lib/puppet/run.rb +5 -1
- data/lib/puppet/scheduler/scheduler.rb +14 -15
- data/lib/puppet/settings.rb +78 -41
- data/lib/puppet/settings/boolean_setting.rb +0 -2
- data/lib/puppet/settings/config_file.rb +0 -2
- data/lib/puppet/settings/directory_setting.rb +0 -2
- data/lib/puppet/settings/duration_setting.rb +0 -2
- data/lib/puppet/settings/enum_setting.rb +16 -0
- data/lib/puppet/settings/file_setting.rb +0 -2
- data/lib/puppet/settings/path_setting.rb +0 -2
- data/lib/puppet/settings/string_setting.rb +0 -3
- data/lib/puppet/settings/terminus_setting.rb +0 -2
- data/lib/puppet/ssl/certificate_authority.rb +102 -9
- data/lib/puppet/test/test_helper.rb +1 -0
- data/lib/puppet/transaction.rb +130 -292
- data/lib/puppet/transaction/additional_resource_generator.rb +126 -0
- data/lib/puppet/transaction/event.rb +16 -1
- data/lib/puppet/transaction/report.rb +34 -14
- data/lib/puppet/transaction/resource_harness.rb +16 -19
- data/lib/puppet/type.rb +59 -53
- data/lib/puppet/type/component.rb +0 -2
- data/lib/puppet/type/cron.rb +13 -2
- data/lib/puppet/type/exec.rb +5 -7
- data/lib/puppet/type/file.rb +9 -32
- data/lib/puppet/type/file/content.rb +4 -1
- data/lib/puppet/type/file/ctime.rb +3 -1
- data/lib/puppet/type/file/ensure.rb +1 -1
- data/lib/puppet/type/file/mode.rb +0 -1
- data/lib/puppet/type/file/mtime.rb +2 -1
- data/lib/puppet/type/group.rb +7 -9
- data/lib/puppet/type/host.rb +1 -2
- data/lib/puppet/type/mcx.rb +0 -1
- data/lib/puppet/type/mount.rb +38 -6
- data/lib/puppet/type/package.rb +2 -2
- data/lib/puppet/type/resources.rb +5 -4
- data/lib/puppet/type/schedule.rb +1 -4
- data/lib/puppet/type/selmodule.rb +1 -1
- data/lib/puppet/type/service.rb +1 -3
- data/lib/puppet/type/tidy.rb +3 -3
- data/lib/puppet/type/user.rb +9 -13
- data/lib/puppet/type/yumrepo.rb +11 -7
- data/lib/puppet/util.rb +14 -7
- data/lib/puppet/util/autoload.rb +0 -1
- data/lib/puppet/util/backups.rb +1 -3
- data/lib/puppet/util/classgen.rb +1 -1
- data/lib/puppet/util/command_line/puppet_option_parser.rb +1 -3
- data/lib/puppet/util/command_line/trollop.rb +1 -1
- data/lib/puppet/util/constant_inflector.rb +1 -2
- data/lib/puppet/util/errors.rb +1 -0
- data/lib/puppet/util/file_watcher.rb +28 -0
- data/lib/puppet/util/fileparsing.rb +1 -3
- data/lib/puppet/util/filetype.rb +0 -1
- data/lib/puppet/util/http_proxy.rb +38 -0
- data/lib/puppet/util/ldap/manager.rb +1 -2
- data/lib/puppet/util/log.rb +31 -10
- data/lib/puppet/util/log/destinations.rb +0 -50
- data/lib/puppet/util/metric.rb +8 -1
- data/lib/puppet/util/monkey_patches.rb +14 -148
- data/lib/puppet/util/network_device/cisco/facts.rb +1 -1
- data/lib/puppet/util/network_device/config.rb +6 -9
- data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
- data/lib/puppet/util/pidlock.rb +3 -0
- data/lib/puppet/util/posix.rb +1 -1
- data/lib/puppet/util/profiler.rb +1 -1
- data/lib/puppet/util/rdoc.rb +1 -1
- data/lib/puppet/util/rdoc/generators/puppet_generator.rb +0 -1
- data/lib/puppet/util/rdoc/generators/template/puppet/puppet.rb +50 -42
- data/lib/puppet/util/retryaction.rb +0 -1
- data/lib/puppet/util/symbolic_file_mode.rb +5 -1
- data/lib/puppet/util/tagging.rb +0 -2
- data/lib/puppet/util/warnings.rb +3 -0
- data/lib/puppet/util/watched_file.rb +37 -0
- data/lib/puppet/util/watcher.rb +17 -0
- data/lib/puppet/util/watcher/change_watcher.rb +33 -0
- data/lib/puppet/util/watcher/periodic_watcher.rb +37 -0
- data/lib/puppet/util/watcher/timer.rb +19 -0
- data/lib/puppet/util/windows/user.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/lib/puppetx.rb +109 -0
- data/lib/puppetx/puppet/bindings_scheme_handler.rb +130 -0
- data/lib/puppetx/puppet/hiera2_backend.rb +31 -0
- data/lib/puppetx/puppet/syntax_checker.rb +91 -0
- data/lib/puppetx/puppetlabs/syntax_checkers/json.rb +39 -0
- data/lib/semver.rb +1 -1
- data/man/man8/puppet-kick.8 +1 -1
- data/spec/fixtures/integration/provider/cron/crontab/unspecialized +15 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/binder_config.yaml +18 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/hiera.yaml +8 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/common.yaml +1 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/hiera.yaml +10 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/binder_config.yaml +19 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/common.yaml +1 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/hiera.yaml +11 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/localhost.yaml +1 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/common.yaml +3 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/hiera.yaml +13 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppet/bindings/awesome/default.rb +4 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_backend.rb +11 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_scheme_handler.rb +18 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/localhost.yaml +1 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/common.yaml +3 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/hiera_config.yaml +9 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/common.yaml +2 -0
- data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/hiera.yaml +11 -0
- data/spec/fixtures/unit/pops/binder/config/binder_config/ok/binder_config.yaml +9 -0
- data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/hiera.yaml +9 -0
- data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.json +9 -0
- data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.yaml +5 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/bad_syntax/hiera.yaml +10 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/malformed_hierarchy/hiera.yaml +8 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/missing/foo.txt +1 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/no_backends/hiera.yaml +7 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/no_hierarchy/hiera.yaml +4 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/not_a_hash/hiera.yaml +2 -0
- data/spec/fixtures/unit/pops/binder/hiera2/config/ok/hiera.yaml +8 -0
- data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/empty/common.yaml +0 -0
- data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/invalid/common.yaml +1 -0
- data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/ok/common.yaml +2 -0
- data/spec/fixtures/unit/provider/package/openbsd/pkginfo_flavors.list +2 -0
- data/spec/integration/agent/logging_spec.rb +178 -0
- data/spec/integration/configurer_spec.rb +1 -1
- data/spec/integration/defaults_spec.rb +0 -6
- data/spec/integration/network/authconfig_spec.rb +19 -0
- data/spec/integration/network/server/webrick_spec.rb +10 -11
- data/spec/integration/parser/catalog_spec.rb +85 -0
- data/spec/integration/provider/cron/crontab_spec.rb +11 -0
- data/spec/integration/provider/mount_spec.rb +1 -0
- data/spec/integration/transaction_spec.rb +8 -8
- data/spec/integration/type/file_spec.rb +1 -1
- data/spec/integration/util/settings_spec.rb +58 -11
- data/spec/lib/matchers/include_in_order.rb +21 -0
- data/spec/lib/matchers/include_in_order_spec.rb +30 -0
- data/spec/lib/matchers/relationship_graph_matchers.rb +48 -0
- data/spec/lib/puppet_spec/compiler.rb +24 -0
- data/spec/lib/puppet_spec/pops.rb +16 -0
- data/spec/spec_helper.rb +0 -1
- data/spec/unit/application/agent_spec.rb +145 -145
- data/spec/unit/application/apply_spec.rb +1 -1
- data/spec/unit/application/doc_spec.rb +1 -1
- data/spec/unit/application/face_base_spec.rb +3 -3
- data/spec/unit/application/facts_spec.rb +1 -0
- data/spec/unit/application/master_spec.rb +0 -15
- data/spec/unit/application/queue_spec.rb +6 -12
- data/spec/unit/application/resource_spec.rb +1 -1
- data/spec/unit/configurer/fact_handler_spec.rb +19 -50
- data/spec/unit/configurer_spec.rb +23 -7
- data/spec/unit/daemon_spec.rb +97 -121
- data/spec/unit/defaults_spec.rb +44 -0
- data/spec/unit/face/node_spec.rb +2 -2
- data/spec/unit/file_serving/configuration/parser_spec.rb +23 -33
- data/spec/unit/file_serving/configuration_spec.rb +2 -2
- data/spec/unit/file_serving/mount/file_spec.rb +4 -4
- data/spec/unit/forge/repository_spec.rb +9 -29
- data/spec/unit/graph/key_spec.rb +41 -0
- data/spec/unit/{rb_tree_map_spec.rb → graph/rb_tree_map_spec.rb} +7 -7
- data/spec/unit/graph/relationship_graph_spec.rb +393 -0
- data/spec/unit/graph/sequential_prioritizer_spec.rb +32 -0
- data/spec/unit/{simple_graph_spec.rb → graph/simple_graph.rb} +42 -254
- data/spec/unit/graph/title_hash_prioritizer_spec.rb +49 -0
- data/spec/unit/hiera_puppet_spec.rb +1 -1
- data/spec/unit/indirector/catalog/active_record_spec.rb +4 -2
- data/spec/unit/indirector/catalog/compiler_spec.rb +20 -26
- data/spec/unit/indirector/face_spec.rb +1 -1
- data/spec/unit/indirector/facts/facter_spec.rb +11 -1
- data/spec/unit/indirector/facts/network_device_spec.rb +11 -1
- data/spec/unit/indirector/hiera_spec.rb +1 -1
- data/spec/unit/indirector/instrumentation_data/local_spec.rb +1 -1
- data/spec/unit/indirector/instrumentation_listener/local_spec.rb +1 -1
- data/spec/unit/indirector/request_spec.rb +92 -39
- data/spec/unit/indirector/rest_spec.rb +1 -0
- data/spec/unit/indirector_spec.rb +2 -2
- data/spec/unit/interface/option_builder_spec.rb +1 -0
- data/spec/unit/interface/option_spec.rb +1 -0
- data/spec/unit/interface_spec.rb +2 -2
- data/spec/unit/module_tool/applications/installer_spec.rb +49 -2
- data/spec/unit/module_tool/metadata_spec.rb +13 -0
- data/spec/unit/network/authstore_spec.rb +1 -1
- data/spec/unit/network/format_handler_spec.rb +33 -282
- data/spec/unit/network/format_support_spec.rb +199 -0
- data/spec/unit/network/formats_spec.rb +2 -2
- data/spec/unit/network/http/connection_spec.rb +88 -7
- data/spec/unit/network/http/handler_spec.rb +271 -249
- data/spec/unit/network/http/rack/rest_spec.rb +1 -1
- data/spec/unit/network/http/webrick/rest_spec.rb +73 -22
- data/spec/unit/network/http_pool_spec.rb +40 -0
- data/spec/unit/network/server_spec.rb +18 -207
- data/spec/unit/node/facts_spec.rb +68 -17
- data/spec/unit/other/selinux_spec.rb +24 -20
- data/spec/unit/parameter/boolean_spec.rb +25 -0
- data/spec/unit/parameter/value_collection_spec.rb +7 -7
- data/spec/unit/parameter_spec.rb +10 -13
- data/spec/unit/parser/ast/function_spec.rb +4 -4
- data/spec/unit/parser/ast/leaf_spec.rb +45 -6
- data/spec/unit/parser/collector_spec.rb +3 -3
- data/spec/unit/parser/compiler_spec.rb +4 -3
- data/spec/unit/parser/functions/create_resources_spec.rb +9 -25
- data/spec/unit/parser/functions/extlookup_spec.rb +2 -2
- data/spec/unit/parser/functions/hiera_include_spec.rb +12 -0
- data/spec/unit/parser/functions/lookup_spec.rb +96 -0
- data/spec/unit/parser/functions/regsubst_spec.rb +2 -2
- data/spec/unit/parser/functions/split_spec.rb +2 -2
- data/spec/unit/parser/functions/sprintf_spec.rb +1 -1
- data/spec/unit/parser/functions/versioncmp_spec.rb +2 -2
- data/spec/unit/parser/functions_spec.rb +7 -7
- data/spec/unit/parser/lexer_spec.rb +1 -1
- data/spec/unit/parser/methods/collect_spec.rb +43 -0
- data/spec/unit/parser/resource_spec.rb +9 -9
- data/spec/unit/parser/scope_spec.rb +45 -2
- data/spec/unit/parser/type_loader_spec.rb +159 -175
- data/spec/unit/pops/binder/binder_spec.rb +62 -0
- data/spec/unit/pops/binder/bindings_checker_spec.rb +196 -0
- data/spec/unit/pops/binder/bindings_composer_spec.rb +89 -0
- data/spec/unit/pops/binder/bindings_validator_factory_spec.rb +18 -0
- data/spec/unit/pops/binder/config/binder_config_spec.rb +48 -0
- data/spec/unit/pops/binder/hiera2/bindings_provider_spec.rb +74 -0
- data/spec/unit/pops/binder/hiera2/config_spec.rb +61 -0
- data/spec/unit/pops/binder/hiera2/yaml_backend_spec.rb +33 -0
- data/spec/unit/pops/binder/injector_spec.rb +789 -0
- data/spec/unit/pops/containment_spec.rb +1 -0
- data/spec/unit/pops/issues_spec.rb +1 -1
- data/spec/unit/pops/parser/evaluating_parser_spec.rb +88 -0
- data/spec/unit/pops/parser/lexer_spec.rb +1 -1
- data/spec/unit/pops/parser/parse_calls_spec.rb +4 -0
- data/spec/unit/pops/parser/parser_spec.rb +1 -1
- data/spec/unit/pops/types/type_calculator_spec.rb +484 -0
- data/spec/unit/pops/types/type_factory_spec.rb +65 -0
- data/spec/unit/pops/types/type_parser_spec.rb +93 -0
- data/spec/unit/property/list_spec.rb +1 -1
- data/spec/unit/property/ordered_list_spec.rb +1 -1
- data/spec/unit/provider/aixobject_spec.rb +101 -0
- data/spec/unit/provider/augeas/augeas_spec.rb +14 -3
- data/spec/unit/provider/mcx/mcxcontent_spec.rb +52 -16
- data/spec/unit/provider/mount/parsed_spec.rb +44 -56
- data/spec/unit/provider/mount_spec.rb +11 -2
- data/spec/unit/provider/naginator_spec.rb +8 -0
- data/spec/unit/provider/package/apt_spec.rb +5 -1
- data/spec/unit/provider/package/aptitude_spec.rb +9 -5
- data/spec/unit/provider/package/aptrpm_spec.rb +2 -2
- data/spec/unit/provider/package/dpkg_spec.rb +274 -99
- data/spec/unit/provider/package/openbsd_spec.rb +84 -1
- data/spec/unit/provider/package/opkg_spec.rb +3 -3
- data/spec/unit/provider/package/pip_spec.rb +16 -0
- data/spec/unit/provider/package/pkgdmg_spec.rb +62 -7
- data/spec/unit/provider/package/rpm_spec.rb +112 -21
- data/spec/unit/provider/package/urpmi.rb +80 -0
- data/spec/unit/provider/package/windows/exe_package_spec.rb +1 -1
- data/spec/unit/provider/package/yum_spec.rb +85 -0
- data/spec/unit/provider/package/zypper_spec.rb +25 -6
- data/spec/unit/provider/parsedfile_spec.rb +3 -2
- data/spec/unit/provider/service/init_spec.rb +10 -10
- data/spec/unit/provider/service/openrc_spec.rb +16 -0
- data/spec/unit/provider/service/openwrt_spec.rb +1 -1
- data/spec/unit/provider/service/redhat_spec.rb +7 -0
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +2 -2
- data/spec/unit/provider/user/aix_spec.rb +89 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +11 -4
- data/spec/unit/provider/user/user_role_add_spec.rb +18 -0
- data/spec/unit/provider_spec.rb +2 -13
- data/spec/unit/reports/http_spec.rb +1 -1
- data/spec/unit/resource/catalog_spec.rb +23 -97
- data/spec/unit/resource/resource_type.json +34 -0
- data/spec/unit/resource/status_spec.rb +56 -0
- data/spec/unit/resource/type_collection_spec.rb +6 -6
- data/spec/unit/resource/type_spec.rb +25 -5
- data/spec/unit/resource_spec.rb +68 -24
- data/spec/unit/run_spec.rb +16 -0
- data/spec/unit/scheduler/scheduler_spec.rb +14 -27
- data/spec/unit/semver_spec.rb +5 -0
- data/spec/unit/settings/enum_setting_spec.rb +27 -0
- data/spec/unit/settings_spec.rb +53 -44
- data/spec/unit/ssl/certificate_authority_spec.rb +155 -19
- data/spec/unit/transaction/additional_resource_generator_spec.rb +419 -0
- data/spec/unit/transaction/event_manager_spec.rb +2 -2
- data/spec/unit/transaction/event_spec.rb +57 -0
- data/spec/unit/transaction/report_spec.rb +66 -0
- data/spec/unit/transaction/resource_harness_spec.rb +27 -20
- data/spec/unit/transaction_spec.rb +182 -390
- data/spec/unit/type/augeas_spec.rb +3 -3
- data/spec/unit/type/component_spec.rb +0 -9
- data/spec/unit/type/computer_spec.rb +1 -1
- data/spec/unit/type/cron_spec.rb +2 -2
- data/spec/unit/type/exec_spec.rb +4 -2
- data/spec/unit/type/file/content_spec.rb +11 -0
- data/spec/unit/type/file/group_spec.rb +1 -1
- data/spec/unit/type/file_spec.rb +16 -8
- data/spec/unit/type/mount_spec.rb +445 -259
- data/spec/unit/type/package_spec.rb +4 -4
- data/spec/unit/type/resources_spec.rb +30 -1
- data/spec/unit/type/user_spec.rb +26 -3
- data/spec/unit/type/yumrepo_spec.rb +7 -27
- data/spec/unit/type/zone_spec.rb +4 -1
- data/spec/unit/type_spec.rb +66 -33
- data/spec/unit/util/backups_spec.rb +3 -3
- data/spec/unit/util/http_proxy_spec.rb +83 -0
- data/spec/unit/util/log_spec.rb +79 -8
- data/spec/unit/util/metric_spec.rb +12 -0
- data/spec/unit/util/monkey_patches_spec.rb +6 -0
- data/spec/unit/util/network_device/config_spec.rb +26 -64
- data/spec/unit/util/pidlock_spec.rb +4 -1
- data/spec/unit/util/tagging_spec.rb +5 -9
- data/spec/unit/util/warnings_spec.rb +1 -1
- data/spec/unit/util/watched_file_spec.rb +52 -0
- data/spec/unit/util/watcher/periodic_watcher_spec.rb +52 -0
- data/spec/unit/util/watcher_spec.rb +56 -0
- data/spec/unit/util_spec.rb +16 -0
- metadata +2767 -2576
- data/ext/debian/puppet.manpages +0 -32
- data/ext/osx/PackageInfo.plist +0 -36
- data/ext/osx/createpackage.sh +0 -187
- data/ext/redhat/rundir-perms.patch +0 -28
- data/lib/puppet/external/base64.rb +0 -19
- data/lib/puppet/util/graph.rb +0 -27
- data/lib/puppet/util/loadedfile.rb +0 -61
- data/lib/puppet/util/log_paths.rb +0 -22
- data/lib/puppet/util/subclass_loader.rb +0 -78
- data/spec/monkey_patches/publicize_methods.rb +0 -11
- data/spec/unit/util/loadedfile_spec.rb +0 -71
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/pops'
|
3
|
+
require 'puppet_spec/pops'
|
4
|
+
|
5
|
+
# A Backend class that doesn't implement the needed API
|
6
|
+
class Puppet::Pops::Binder::Hiera2::Bad_backend
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'The hiera2 config' do
|
10
|
+
|
11
|
+
include PuppetSpec::Pops
|
12
|
+
|
13
|
+
let(:acceptor) { Puppet::Pops::Validation::Acceptor.new() }
|
14
|
+
let(:diag) { Puppet::Pops::Binder::Hiera2::DiagnosticProducer.new(acceptor) }
|
15
|
+
|
16
|
+
def config_dir(config_name)
|
17
|
+
File.dirname(my_fixture("#{config_name}/hiera.yaml"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_config_issue(config_name, issue)
|
21
|
+
Puppet::Pops::Binder::Hiera2::Config.new(config_dir(config_name), diag)
|
22
|
+
acceptor.should have_issue(issue)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should load and validate OK configuration' do
|
26
|
+
Puppet::Pops::Binder::Hiera2::Config.new(config_dir('ok'), diag)
|
27
|
+
acceptor.errors_or_warnings?.should() == false
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should report missing config file' do
|
31
|
+
Puppet::Pops::Binder::Hiera2::Config.new(File.dirname(my_fixture('missing/foo.txt')), diag)
|
32
|
+
acceptor.should have_issue(Puppet::Pops::Binder::Hiera2::Issues::CONFIG_FILE_NOT_FOUND)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should report when config is not a hash' do
|
36
|
+
test_config_issue('not_a_hash', Puppet::Pops::Binder::Hiera2::Issues::CONFIG_IS_NOT_HASH)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should report when config has syntax problems' do
|
40
|
+
if RUBY_VERSION.start_with?("1.8")
|
41
|
+
# Yes, it is a lobotomy or 2 short of a full brain...
|
42
|
+
# if a hash key is not in quotes it continues on the next line and gobbles what is there instead
|
43
|
+
# of reporting an error
|
44
|
+
test_config_issue('bad_syntax', Puppet::Pops::Binder::Hiera2::Issues::MISSING_HIERARCHY)
|
45
|
+
else
|
46
|
+
test_config_issue('bad_syntax', Puppet::Pops::Binder::Hiera2::Issues::CONFIG_FILE_SYNTAX_ERROR)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should report when config has no hierarchy defined' do
|
51
|
+
test_config_issue('no_hierarchy', Puppet::Pops::Binder::Hiera2::Issues::MISSING_HIERARCHY)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should report when config has no backends defined' do
|
55
|
+
test_config_issue('no_backends', Puppet::Pops::Binder::Hiera2::Issues::MISSING_BACKENDS)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should report when config hierarchy is malformed' do
|
59
|
+
test_config_issue('malformed_hierarchy', Puppet::Pops::Binder::Hiera2::Issues::CATEGORY_MUST_BE_THREE_ELEMENT_ARRAY)
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/pops'
|
3
|
+
|
4
|
+
describe "Hiera2 YAML backend" do
|
5
|
+
|
6
|
+
include PuppetSpec::Files
|
7
|
+
|
8
|
+
def fixture_dir(config_name)
|
9
|
+
my_fixture("#{config_name}")
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
Puppet[:binder] = true
|
14
|
+
require 'puppetx'
|
15
|
+
require 'puppet/pops/binder/hiera2/yaml_backend'
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:all) do
|
19
|
+
Puppet[:binder] = false
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns the expected hash from a valid yaml file" do
|
23
|
+
Puppet::Pops::Binder::Hiera2::YamlBackend.new().read_data(fixture_dir("ok"), "common").should == {'brillig' => 'slithy'}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns an empty hash from an empty yaml file" do
|
27
|
+
Puppet::Pops::Binder::Hiera2::YamlBackend.new().read_data(fixture_dir("empty"), "common").should == {}
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns an empty hash from an invalid yaml file" do
|
31
|
+
Puppet::Pops::Binder::Hiera2::YamlBackend.new().read_data(fixture_dir("invalid"), "common").should == {}
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,789 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/pops'
|
3
|
+
|
4
|
+
module InjectorSpecModule
|
5
|
+
def injector(binder)
|
6
|
+
Puppet::Pops::Binder::Injector.new(binder)
|
7
|
+
end
|
8
|
+
|
9
|
+
def factory
|
10
|
+
Puppet::Pops::Binder::BindingsFactory
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_layer_with_empty_bindings
|
14
|
+
factory.named_layer('test-layer', factory.named_bindings('test').model)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_layer_with_bindings(*bindings)
|
18
|
+
factory.named_layer('test-layer', *bindings)
|
19
|
+
end
|
20
|
+
|
21
|
+
def null_scope()
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def type_calculator
|
26
|
+
Puppet::Pops::Types::TypeCalculator
|
27
|
+
end
|
28
|
+
|
29
|
+
def type_factory
|
30
|
+
Puppet::Pops::Types::TypeFactory
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a binder with the effective categories highest/test, node/kermit, environment/dev (and implicit 'common')
|
34
|
+
#
|
35
|
+
def binder_with_categories
|
36
|
+
b = Puppet::Pops::Binder::Binder.new()
|
37
|
+
b.define_categories(factory.categories(['highest', 'test', 'node', 'kermit', 'environment','dev']))
|
38
|
+
b
|
39
|
+
end
|
40
|
+
|
41
|
+
class TestDuck
|
42
|
+
end
|
43
|
+
|
44
|
+
class Daffy < TestDuck
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
class AngryDuck < TestDuck
|
49
|
+
# Supports assisted inject, returning a Donald duck as the default impl of Duck
|
50
|
+
def self.inject(injector, scope, binding, *args)
|
51
|
+
Donald.new()
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Donald < AngryDuck
|
56
|
+
end
|
57
|
+
|
58
|
+
class ArneAnka < AngryDuck
|
59
|
+
attr_reader :label
|
60
|
+
|
61
|
+
def initialize()
|
62
|
+
@label = 'A Swedish angry cartoon duck'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ScroogeMcDuck < TestDuck
|
67
|
+
attr_reader :fortune
|
68
|
+
|
69
|
+
# Supports assisted inject, returning an ScroogeMcDuck with 1$ fortune or first arg in args
|
70
|
+
# Note that when injected (via instance producer, or implict assisted inject, the inject method
|
71
|
+
# always wins.
|
72
|
+
def self.inject(injector, scope, binding, *args)
|
73
|
+
self.new(args[0].nil? ? 1 : args[0])
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize(fortune)
|
77
|
+
@fortune = fortune
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class NamedDuck < TestDuck
|
82
|
+
attr_reader :name
|
83
|
+
def initialize(name)
|
84
|
+
@name = name
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Test custom producer that on each produce returns a duck that is twice as rich as its predecessor
|
89
|
+
class ScroogeProducer < Puppet::Pops::Binder::Producers::Producer
|
90
|
+
attr_reader :next_capital
|
91
|
+
def initialize
|
92
|
+
@next_capital = 100
|
93
|
+
end
|
94
|
+
def produce(scope)
|
95
|
+
ScroogeMcDuck.new(@next_capital *= 2)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'Injector' do
|
101
|
+
include InjectorSpecModule
|
102
|
+
|
103
|
+
let(:bindings) { factory.named_bindings('test') }
|
104
|
+
let(:scope) { null_scope()}
|
105
|
+
let(:duck_type) { type_factory.ruby(InjectorSpecModule::TestDuck) }
|
106
|
+
|
107
|
+
let(:binder) { Puppet::Pops::Binder::Binder.new()}
|
108
|
+
|
109
|
+
let(:cbinder) do
|
110
|
+
b = Puppet::Pops::Binder::Binder.new()
|
111
|
+
b.define_categories(factory.categories([]))
|
112
|
+
b
|
113
|
+
end
|
114
|
+
|
115
|
+
let(:lbinder) do
|
116
|
+
cbinder.define_layers(layered_bindings)
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
let(:layered_bindings) { factory.layered_bindings(test_layer_with_bindings(bindings.model)) }
|
121
|
+
#let(:xinjector) { Puppet::Pops::Binder::Injector.new(lbinder) }
|
122
|
+
|
123
|
+
context 'When created' do
|
124
|
+
it 'should raise an error when given binder is not configured at all' do
|
125
|
+
expect { Puppet::Pops::Binder::Injector.new(binder()) }.to raise_error(/Given Binder is not configured/)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should raise an error if binder has categories, but is not completely configured' do
|
129
|
+
expect { Puppet::Pops::Binder::Injector.new(cbinder) }.to raise_error(/Given Binder is not configured/)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should not raise an error if binder is configured' do
|
133
|
+
lbinder.configured?().should == true # of something is very wrong
|
134
|
+
expect { injector(lbinder) }.to_not raise_error
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should create an empty injector given an empty binder' do
|
138
|
+
expect { cbinder.define_layers(layered_bindings) }.to_not raise_exception
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should be possible to reference the TypeCalculator" do
|
142
|
+
injector(lbinder).type_calculator.is_a?(Puppet::Pops::Types::TypeCalculator).should == true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should be possible to reference the KeyFactory" do
|
146
|
+
injector(lbinder).key_factory.is_a?(Puppet::Pops::Binder::KeyFactory).should == true
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "When looking up objects" do
|
151
|
+
it 'lookup(scope, name) finds bound object of type Data with given name' do
|
152
|
+
bindings.bind().name('a_string').to('42')
|
153
|
+
injector(lbinder).lookup(scope, 'a_string').should == '42'
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'a block transforming the result can be given' do
|
157
|
+
it 'that transform a found value given scope and value' do
|
158
|
+
bindings.bind().name('a_string').to('42')
|
159
|
+
injector(lbinder).lookup(scope, 'a_string') {|zcope, val| val + '42' }.should == '4242'
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'that transform a found value given only value' do
|
163
|
+
bindings.bind().name('a_string').to('42')
|
164
|
+
injector(lbinder).lookup(scope, 'a_string') {|val| val + '42' }.should == '4242'
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'that produces a default value when entry is missing' do
|
168
|
+
bindings.bind().name('a_string').to('42')
|
169
|
+
injector(lbinder).lookup(scope, 'a_non_existing_string') {|val| val ? (raise Error, "Should not happen") : '4242' }.should == '4242'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "and class is not bound" do
|
174
|
+
it "assisted inject kicks in for classes with zero args constructor" do
|
175
|
+
duck_type = type_factory.ruby(InjectorSpecModule::Daffy)
|
176
|
+
injector = injector(lbinder)
|
177
|
+
injector.lookup(scope, duck_type).is_a?(InjectorSpecModule::Daffy).should == true
|
178
|
+
injector.lookup_producer(scope, duck_type).produce(scope).is_a?(InjectorSpecModule::Daffy).should == true
|
179
|
+
end
|
180
|
+
|
181
|
+
it "assisted inject produces same instance on lookup but not on lookup producer" do
|
182
|
+
duck_type = type_factory.ruby(InjectorSpecModule::Daffy)
|
183
|
+
injector = injector(lbinder)
|
184
|
+
d1 = injector.lookup(scope, duck_type)
|
185
|
+
d2 = injector.lookup(scope, duck_type)
|
186
|
+
d1.equal?(d2).should == true
|
187
|
+
|
188
|
+
d1 = injector.lookup_producer(scope, duck_type).produce(scope)
|
189
|
+
d2 = injector.lookup_producer(scope, duck_type).produce(scope)
|
190
|
+
d1.equal?(d2).should == false
|
191
|
+
end
|
192
|
+
|
193
|
+
it "assisted inject kicks in for classes with a class inject method" do
|
194
|
+
duck_type = type_factory.ruby(InjectorSpecModule::ScroogeMcDuck)
|
195
|
+
injector = injector(lbinder)
|
196
|
+
# Do not pass any arguments, the ScroogeMcDuck :inject method should pick 1 by default
|
197
|
+
# This tests zero args passed
|
198
|
+
injector.lookup(scope, duck_type).fortune.should == 1
|
199
|
+
injector.lookup_producer(scope, duck_type).produce(scope).fortune.should == 1
|
200
|
+
end
|
201
|
+
|
202
|
+
it "assisted inject selects the inject method if it exists over a zero args constructor" do
|
203
|
+
injector = injector(lbinder)
|
204
|
+
duck_type = type_factory.ruby(InjectorSpecModule::AngryDuck)
|
205
|
+
injector.lookup(scope, duck_type).is_a?(InjectorSpecModule::Donald).should == true
|
206
|
+
injector.lookup_producer(scope, duck_type).produce(scope).is_a?(InjectorSpecModule::Donald).should == true
|
207
|
+
end
|
208
|
+
|
209
|
+
it "assisted inject selects the zero args constructor if injector is from a superclass" do
|
210
|
+
injector = injector(lbinder)
|
211
|
+
duck_type = type_factory.ruby(InjectorSpecModule::ArneAnka)
|
212
|
+
injector.lookup(scope, duck_type).is_a?(InjectorSpecModule::ArneAnka).should == true
|
213
|
+
injector.lookup_producer(scope, duck_type).produce(scope).is_a?(InjectorSpecModule::ArneAnka).should == true
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'and conditionals are in use' do
|
218
|
+
let(:binder) { binder_with_categories()}
|
219
|
+
let(:lbinder) { binder.define_layers(layered_bindings) }
|
220
|
+
|
221
|
+
it "should be possible to shadow a bound value in a higher precedented category" do
|
222
|
+
bindings.bind().name('a_string').to('42')
|
223
|
+
bindings.when_in_category('environment', 'dev').bind().name('a_string').to('43')
|
224
|
+
bindings.when_in_category('node', 'kermit').bind().name('a_string').to('being green')
|
225
|
+
injector(lbinder).lookup(scope,'a_string').should == 'being green'
|
226
|
+
end
|
227
|
+
|
228
|
+
it "shadowing should not happen when not in a category" do
|
229
|
+
bindings.bind().name('a_string').to('42')
|
230
|
+
bindings.when_in_category('environment', 'dev').bind().name('a_string').to('43')
|
231
|
+
bindings.when_in_category('node', 'piggy').bind().name('a_string').to('being green')
|
232
|
+
injector(lbinder).lookup(scope,'a_string').should == '43'
|
233
|
+
end
|
234
|
+
|
235
|
+
it "multiple predicates makes binding more specific" do
|
236
|
+
bindings.bind().name('a_string').to('42')
|
237
|
+
bindings.when_in_category('environment', 'dev').bind().name('a_string').to('43')
|
238
|
+
bindings.when_in_category('node', 'kermit').bind().name('a_string').to('being green')
|
239
|
+
bindings.when_in_categories({'node'=>'kermit', 'environment'=>'dev'}).bind().name('a_string').to('being dev green')
|
240
|
+
injector(lbinder).lookup(scope,'a_string').should == 'being dev green'
|
241
|
+
end
|
242
|
+
|
243
|
+
it "multiple predicates makes binding more specific, but not more specific than higher precedence" do
|
244
|
+
bindings.bind().name('a_string').to('42')
|
245
|
+
bindings.when_in_category('environment', 'dev').bind().name('a_string').to('43')
|
246
|
+
bindings.when_in_category('node', 'kermit').bind().name('a_string').to('being green')
|
247
|
+
bindings.when_in_categories({'node'=>'kermit', 'environment'=>'dev'}).bind().name('a_string').to('being dev green')
|
248
|
+
bindings.when_in_category('highest', 'test').bind().name('a_string').to('bazinga')
|
249
|
+
injector(lbinder).lookup(scope,'a_string').should == 'bazinga'
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context "and multiple layers are in use" do
|
254
|
+
let(:binder) { binder_with_categories()}
|
255
|
+
|
256
|
+
it "a higher layer shadows anything in a lower layer" do
|
257
|
+
bindings1 = factory.named_bindings('test1')
|
258
|
+
bindings1.when_in_category("highest", "test").bind().name('a_string').to('bad stuff')
|
259
|
+
lower_layer = factory.named_layer('lower-layer', bindings1.model)
|
260
|
+
|
261
|
+
bindings2 = factory.named_bindings('test2')
|
262
|
+
bindings2.bind().name('a_string').to('good stuff')
|
263
|
+
higher_layer = factory.named_layer('higher-layer', bindings2.model)
|
264
|
+
|
265
|
+
binder.define_layers(factory.layered_bindings(higher_layer, lower_layer))
|
266
|
+
injector = injector(binder)
|
267
|
+
injector.lookup(scope,'a_string').should == 'good stuff'
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context "and dealing with Data types" do
|
272
|
+
let(:binder) { binder_with_categories()}
|
273
|
+
let(:lbinder) { binder.define_layers(layered_bindings) }
|
274
|
+
|
275
|
+
it "should treat all data as same type w.r.t. key" do
|
276
|
+
bindings.bind().name('a_string').to('42')
|
277
|
+
bindings.bind().name('an_int').to(43)
|
278
|
+
bindings.bind().name('a_float').to(3.14)
|
279
|
+
bindings.bind().name('a_boolean').to(true)
|
280
|
+
bindings.bind().name('an_array').to([1,2,3])
|
281
|
+
bindings.bind().name('a_hash').to({'a'=>1,'b'=>2,'c'=>3})
|
282
|
+
|
283
|
+
injector = injector(lbinder)
|
284
|
+
injector.lookup(scope,'a_string').should == '42'
|
285
|
+
injector.lookup(scope,'an_int').should == 43
|
286
|
+
injector.lookup(scope,'a_float').should == 3.14
|
287
|
+
injector.lookup(scope,'a_boolean').should == true
|
288
|
+
injector.lookup(scope,'an_array').should == [1,2,3]
|
289
|
+
injector.lookup(scope,'a_hash').should == {'a'=>1,'b'=>2,'c'=>3}
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should provide type-safe lookup of given type/name" do
|
293
|
+
bindings.bind().string().name('a_string').to('42')
|
294
|
+
bindings.bind().integer().name('an_int').to(43)
|
295
|
+
bindings.bind().float().name('a_float').to(3.14)
|
296
|
+
bindings.bind().boolean().name('a_boolean').to(true)
|
297
|
+
bindings.bind().array_of_data().name('an_array').to([1,2,3])
|
298
|
+
bindings.bind().hash_of_data().name('a_hash').to({'a'=>1,'b'=>2,'c'=>3})
|
299
|
+
|
300
|
+
injector = injector(lbinder)
|
301
|
+
|
302
|
+
# Check lookup using implied Data type
|
303
|
+
injector.lookup(scope,'a_string').should == '42'
|
304
|
+
injector.lookup(scope,'an_int').should == 43
|
305
|
+
injector.lookup(scope,'a_float').should == 3.14
|
306
|
+
injector.lookup(scope,'a_boolean').should == true
|
307
|
+
injector.lookup(scope,'an_array').should == [1,2,3]
|
308
|
+
injector.lookup(scope,'a_hash').should == {'a'=>1,'b'=>2,'c'=>3}
|
309
|
+
|
310
|
+
# Check lookup using expected type
|
311
|
+
injector.lookup(scope,type_factory.string(), 'a_string').should == '42'
|
312
|
+
injector.lookup(scope,type_factory.integer(), 'an_int').should == 43
|
313
|
+
injector.lookup(scope,type_factory.float(),'a_float').should == 3.14
|
314
|
+
injector.lookup(scope,type_factory.boolean(),'a_boolean').should == true
|
315
|
+
injector.lookup(scope,type_factory.array_of_data(),'an_array').should == [1,2,3]
|
316
|
+
injector.lookup(scope,type_factory.hash_of_data(),'a_hash').should == {'a'=>1,'b'=>2,'c'=>3}
|
317
|
+
|
318
|
+
# Check lookup using wrong type
|
319
|
+
expect { injector.lookup(scope,type_factory.integer(), 'a_string')}.to raise_error(/Type error/)
|
320
|
+
expect { injector.lookup(scope,type_factory.string(), 'an_int')}.to raise_error(/Type error/)
|
321
|
+
expect { injector.lookup(scope,type_factory.string(),'a_float')}.to raise_error(/Type error/)
|
322
|
+
expect { injector.lookup(scope,type_factory.string(),'a_boolean')}.to raise_error(/Type error/)
|
323
|
+
expect { injector.lookup(scope,type_factory.string(),'an_array')}.to raise_error(/Type error/)
|
324
|
+
expect { injector.lookup(scope,type_factory.string(),'a_hash')}.to raise_error(/Type error/)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context "When looking up producer" do
|
330
|
+
it 'the value is produced by calling produce(scope)' do
|
331
|
+
bindings.bind().name('a_string').to('42')
|
332
|
+
injector(lbinder).lookup_producer(scope, 'a_string').produce(scope).should == '42'
|
333
|
+
end
|
334
|
+
|
335
|
+
context 'a block transforming the result can be given' do
|
336
|
+
it 'that transform a found value given scope and producer' do
|
337
|
+
bindings.bind().name('a_string').to('42')
|
338
|
+
injector(lbinder).lookup_producer(scope, 'a_string') {|zcope, p| p.produce(zcope) + '42' }.should == '4242'
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'that transform a found value given only producer' do
|
342
|
+
bindings.bind().name('a_string').to('42')
|
343
|
+
injector(lbinder).lookup_producer(scope, 'a_string') {|p| p.produce(scope) + '42' }.should == '4242'
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'that can produce a default value when entry is not found' do
|
347
|
+
bindings.bind().name('a_string').to('42')
|
348
|
+
injector(lbinder).lookup_producer(scope, 'a_non_existing_string') {|p| p ? (raise Error,"Should not happen") : '4242' }.should == '4242'
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "When dealing with singleton vs. non singleton" do
|
354
|
+
it "should produce the same instance when producer is a singleton" do
|
355
|
+
bindings.bind().name('a_string').to('42')
|
356
|
+
injector = injector(lbinder)
|
357
|
+
a = injector.lookup(scope, 'a_string')
|
358
|
+
b = injector.lookup(scope, 'a_string')
|
359
|
+
a.equal?(b).should == true
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should produce different instances when producer is a non singleton producer" do
|
363
|
+
bindings.bind().name('a_string').to_series_of('42')
|
364
|
+
injector = injector(lbinder)
|
365
|
+
a = injector.lookup(scope, 'a_string')
|
366
|
+
b = injector.lookup(scope, 'a_string')
|
367
|
+
a.should == '42'
|
368
|
+
b.should == '42'
|
369
|
+
a.equal?(b).should == false
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
context "When using the lookup producer" do
|
374
|
+
it "should lookup again to produce a value" do
|
375
|
+
bindings.bind().name('a_string').to_lookup_of('another_string')
|
376
|
+
bindings.bind().name('another_string').to('hello')
|
377
|
+
injector(lbinder).lookup(scope, 'a_string').should == 'hello'
|
378
|
+
end
|
379
|
+
|
380
|
+
it "should produce nil if looked up key does not exist" do
|
381
|
+
bindings.bind().name('a_string').to_lookup_of('non_existing')
|
382
|
+
injector(lbinder).lookup(scope, 'a_string').should == nil
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should report an error if lookup loop is detected" do
|
386
|
+
bindings.bind().name('a_string').to_lookup_of('a_string')
|
387
|
+
expect { injector(lbinder).lookup(scope, 'a_string') }.to raise_error(/Lookup loop/)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
context "When using the hash lookup producer" do
|
392
|
+
it "should lookup a key in looked up hash" do
|
393
|
+
data_hash = type_factory.hash_of_data()
|
394
|
+
bindings.bind().name('a_string').to_hash_lookup_of(data_hash, 'a_hash', 'huey')
|
395
|
+
bindings.bind().name('a_hash').to({'huey' => 'red', 'dewey' => 'blue', 'louie' => 'green'})
|
396
|
+
injector(lbinder).lookup(scope, 'a_string').should == 'red'
|
397
|
+
end
|
398
|
+
|
399
|
+
it "should produce nil if looked up entry does not exist" do
|
400
|
+
data_hash = type_factory.hash_of_data()
|
401
|
+
bindings.bind().name('a_string').to_hash_lookup_of(data_hash, 'non_existing_entry', 'huey')
|
402
|
+
bindings.bind().name('a_hash').to({'huey' => 'red', 'dewey' => 'blue', 'louie' => 'green'})
|
403
|
+
injector(lbinder).lookup(scope, 'a_string').should == nil
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
context "When using the first found producer" do
|
408
|
+
it "should lookup until it finds a value, but not further" do
|
409
|
+
bindings.bind().name('a_string').to_first_found('b_string', 'c_string', 'g_string')
|
410
|
+
bindings.bind().name('c_string').to('hello')
|
411
|
+
bindings.bind().name('g_string').to('Oh, mrs. Smith...')
|
412
|
+
injector(lbinder).lookup(scope, 'a_string').should == 'hello'
|
413
|
+
end
|
414
|
+
|
415
|
+
it "should lookup until it finds a value using mix of type and name, but not further" do
|
416
|
+
bindings.bind().name('a_string').to_first_found('b_string', [type_factory.string, 'c_string'], 'g_string')
|
417
|
+
bindings.bind().name('c_string').to('hello')
|
418
|
+
bindings.bind().name('g_string').to('Oh, mrs. Smith...')
|
419
|
+
injector(lbinder).lookup(scope, 'a_string').should == 'hello'
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context "When producing instances" do
|
424
|
+
it "should lookup an instance of a class without arguments" do
|
425
|
+
bindings.bind().type(duck_type).name('the_duck').to(InjectorSpecModule::Daffy)
|
426
|
+
injector(lbinder).lookup(scope, duck_type, 'the_duck').is_a?(InjectorSpecModule::Daffy).should == true
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should lookup an instance of a class with arguments" do
|
430
|
+
bindings.bind().type(duck_type).name('the_duck').to(InjectorSpecModule::ScroogeMcDuck, 1234)
|
431
|
+
injector = injector(lbinder)
|
432
|
+
|
433
|
+
the_duck = injector.lookup(scope, duck_type, 'the_duck')
|
434
|
+
the_duck.is_a?(InjectorSpecModule::ScroogeMcDuck).should == true
|
435
|
+
the_duck.fortune.should == 1234
|
436
|
+
end
|
437
|
+
|
438
|
+
it "singleton producer should not be recreated between lookups" do
|
439
|
+
bindings.bind().type(duck_type).name('the_duck').to_producer(InjectorSpecModule::ScroogeProducer)
|
440
|
+
injector = injector(lbinder)
|
441
|
+
|
442
|
+
the_duck = injector.lookup(scope, duck_type, 'the_duck')
|
443
|
+
the_duck.is_a?(InjectorSpecModule::ScroogeMcDuck).should == true
|
444
|
+
the_duck.fortune.should == 200
|
445
|
+
|
446
|
+
# singleton, do it again to get next value in series - it is the producer that is a singleton
|
447
|
+
# not the produced value
|
448
|
+
the_duck = injector.lookup(scope, duck_type, 'the_duck')
|
449
|
+
the_duck.is_a?(InjectorSpecModule::ScroogeMcDuck).should == true
|
450
|
+
the_duck.fortune.should == 400
|
451
|
+
|
452
|
+
duck_producer = injector.lookup_producer(scope, duck_type, 'the_duck')
|
453
|
+
duck_producer.produce(scope).fortune.should == 800
|
454
|
+
end
|
455
|
+
|
456
|
+
it "series of producers should recreate producer on each lookup and lookup_producer" do
|
457
|
+
bindings.bind().type(duck_type).name('the_duck').to_producer_series(InjectorSpecModule::ScroogeProducer)
|
458
|
+
injector = injector(lbinder)
|
459
|
+
|
460
|
+
duck_producer = injector.lookup_producer(scope, duck_type, 'the_duck')
|
461
|
+
duck_producer.produce(scope).fortune().should == 200
|
462
|
+
duck_producer.produce(scope).fortune().should == 400
|
463
|
+
|
464
|
+
# series, each lookup gets a new producer (initialized to produce 200)
|
465
|
+
duck_producer = injector.lookup_producer(scope, duck_type, 'the_duck')
|
466
|
+
duck_producer.produce(scope).fortune().should == 200
|
467
|
+
duck_producer.produce(scope).fortune().should == 400
|
468
|
+
|
469
|
+
injector.lookup(scope, duck_type, 'the_duck').fortune().should == 200
|
470
|
+
injector.lookup(scope, duck_type, 'the_duck').fortune().should == 200
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
context "When working with multibind" do
|
475
|
+
context "of hash kind" do
|
476
|
+
it "a multibind produces contributed items keyed by their bound key-name" do
|
477
|
+
hash_of_duck = type_factory.hash_of(duck_type)
|
478
|
+
multibind_id = "ducks"
|
479
|
+
|
480
|
+
bindings.multibind(multibind_id).type(hash_of_duck).name('donalds_nephews')
|
481
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('nephew1').to(InjectorSpecModule::NamedDuck, 'Huey')
|
482
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('nephew2').to(InjectorSpecModule::NamedDuck, 'Dewey')
|
483
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('nephew3').to(InjectorSpecModule::NamedDuck, 'Louie')
|
484
|
+
|
485
|
+
injector = injector(lbinder)
|
486
|
+
the_ducks = injector.lookup(scope, hash_of_duck, "donalds_nephews")
|
487
|
+
the_ducks.size.should == 3
|
488
|
+
the_ducks['nephew1'].name.should == 'Huey'
|
489
|
+
the_ducks['nephew2'].name.should == 'Dewey'
|
490
|
+
the_ducks['nephew3'].name.should == 'Louie'
|
491
|
+
end
|
492
|
+
|
493
|
+
it "is an error to not bind contribution with a name" do
|
494
|
+
hash_of_duck = type_factory.hash_of(duck_type)
|
495
|
+
multibind_id = "ducks"
|
496
|
+
|
497
|
+
bindings.multibind(multibind_id).type(hash_of_duck).name('donalds_nephews')
|
498
|
+
# missing name
|
499
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).to(InjectorSpecModule::NamedDuck, 'Huey')
|
500
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).to(InjectorSpecModule::NamedDuck, 'Dewey')
|
501
|
+
|
502
|
+
expect {
|
503
|
+
the_ducks = injector(lbinder).lookup(scope, hash_of_duck, "donalds_nephews")
|
504
|
+
}.to raise_error(/must have a name/)
|
505
|
+
end
|
506
|
+
|
507
|
+
it "is an error to bind with duplicate key when using default (priority) conflict resolution" do
|
508
|
+
hash_of_duck = type_factory.hash_of(duck_type)
|
509
|
+
multibind_id = "ducks"
|
510
|
+
|
511
|
+
bindings.multibind(multibind_id).type(hash_of_duck).name('donalds_nephews')
|
512
|
+
# missing name
|
513
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('foo').to(InjectorSpecModule::NamedDuck, 'Huey')
|
514
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('foo').to(InjectorSpecModule::NamedDuck, 'Dewey')
|
515
|
+
|
516
|
+
expect {
|
517
|
+
the_ducks = injector(lbinder).lookup(scope, hash_of_duck, "donalds_nephews")
|
518
|
+
}.to raise_error(/Duplicate key/)
|
519
|
+
end
|
520
|
+
|
521
|
+
it "is not an error to bind with duplicate key when using (ignore) conflict resolution" do
|
522
|
+
hash_of_duck = type_factory.hash_of(duck_type)
|
523
|
+
multibind_id = "ducks"
|
524
|
+
|
525
|
+
bindings.multibind(multibind_id).type(hash_of_duck).name('donalds_nephews').producer_options(:conflict_resolution => :ignore)
|
526
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('foo').to(InjectorSpecModule::NamedDuck, 'Huey')
|
527
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('foo').to(InjectorSpecModule::NamedDuck, 'Dewey')
|
528
|
+
|
529
|
+
expect {
|
530
|
+
the_ducks = injector(lbinder).lookup(scope, hash_of_duck, "donalds_nephews")
|
531
|
+
}.to_not raise_error(/Duplicate key/)
|
532
|
+
end
|
533
|
+
|
534
|
+
it "should produce detailed type error message" do
|
535
|
+
hash_of_integer = type_factory.hash_of(type_factory.integer())
|
536
|
+
|
537
|
+
multibind_id = "ints"
|
538
|
+
mb = bindings.multibind(multibind_id).type(hash_of_integer).name('donalds_family')
|
539
|
+
bindings.bind.in_multibind(multibind_id).name('nephew').to('Huey')
|
540
|
+
|
541
|
+
expect { ducks = injector(lbinder).lookup(scope, 'donalds_family')
|
542
|
+
}.to raise_error(%r{expected: Integer, got: String})
|
543
|
+
end
|
544
|
+
|
545
|
+
it "should be possible to combine hash multibind contributions with append on conflict" do
|
546
|
+
# This case uses a multibind of individual strings, but combines them
|
547
|
+
# into an array bound to a hash key
|
548
|
+
# (There are other ways to do this - e.g. have the multibind lookup a multibind
|
549
|
+
# of array type to which nephews are contributed).
|
550
|
+
#
|
551
|
+
hash_of_data = type_factory.hash_of_data()
|
552
|
+
multibind_id = "ducks"
|
553
|
+
mb = bindings.multibind(multibind_id).type(hash_of_data).name('donalds_family')
|
554
|
+
mb.producer_options(:conflict_resolution => :append)
|
555
|
+
|
556
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Huey')
|
557
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Dewey')
|
558
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Louie')
|
559
|
+
bindings.bind.in_multibind(multibind_id).name('uncles').to('Scrooge McDuck')
|
560
|
+
bindings.bind.in_multibind(multibind_id).name('uncles').to('Ludwig Von Drake')
|
561
|
+
|
562
|
+
ducks = injector(lbinder).lookup(scope, 'donalds_family')
|
563
|
+
|
564
|
+
ducks['nephews'].should == ['Huey', 'Dewey', 'Louie']
|
565
|
+
ducks['uncles'].should == ['Scrooge McDuck', 'Ludwig Von Drake']
|
566
|
+
end
|
567
|
+
|
568
|
+
it "should be possible to combine hash multibind contributions with append, flat, and uniq, on conflict" do
|
569
|
+
# This case uses a multibind of individual strings, but combines them
|
570
|
+
# into an array bound to a hash key
|
571
|
+
# (There are other ways to do this - e.g. have the multibind lookup a multibind
|
572
|
+
# of array type to which nephews are contributed).
|
573
|
+
#
|
574
|
+
hash_of_data = type_factory.hash_of_data()
|
575
|
+
multibind_id = "ducks"
|
576
|
+
mb = bindings.multibind(multibind_id).type(hash_of_data).name('donalds_family')
|
577
|
+
mb.producer_options(:conflict_resolution => :append, :flatten => true, :uniq => true)
|
578
|
+
|
579
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Huey')
|
580
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Huey')
|
581
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Dewey')
|
582
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to(['Huey', ['Louie'], 'Dewey'])
|
583
|
+
bindings.bind.in_multibind(multibind_id).name('uncles').to('Scrooge McDuck')
|
584
|
+
bindings.bind.in_multibind(multibind_id).name('uncles').to('Ludwig Von Drake')
|
585
|
+
|
586
|
+
ducks = injector(lbinder).lookup(scope, 'donalds_family')
|
587
|
+
|
588
|
+
ducks['nephews'].should == ['Huey', 'Dewey', 'Louie']
|
589
|
+
ducks['uncles'].should == ['Scrooge McDuck', 'Ludwig Von Drake']
|
590
|
+
end
|
591
|
+
|
592
|
+
it "should fail attempts to append, perform uniq or flatten on type incompatible multibind hash" do
|
593
|
+
hash_of_integer = type_factory.hash_of(type_factory.integer())
|
594
|
+
ids = ["ducks1", "ducks2", "ducks3"]
|
595
|
+
mb = bindings.multibind(ids[0]).type(hash_of_integer).name('broken_family0')
|
596
|
+
mb.producer_options(:conflict_resolution => :append)
|
597
|
+
mb = bindings.multibind(ids[1]).type(hash_of_integer).name('broken_family1')
|
598
|
+
mb.producer_options(:flatten => :true)
|
599
|
+
mb = bindings.multibind(ids[2]).type(hash_of_integer).name('broken_family2')
|
600
|
+
mb.producer_options(:uniq => :true)
|
601
|
+
|
602
|
+
|
603
|
+
binder.define_categories(factory.categories([]))
|
604
|
+
binder.define_layers(factory.layered_bindings(test_layer_with_bindings(bindings.model)))
|
605
|
+
injector = injector(binder)
|
606
|
+
expect { injector.lookup(scope, 'broken_family0')}.to raise_error(/:conflict_resolution => :append/)
|
607
|
+
expect { injector.lookup(scope, 'broken_family1')}.to raise_error(/:flatten/)
|
608
|
+
expect { injector.lookup(scope, 'broken_family2')}.to raise_error(/:uniq/)
|
609
|
+
end
|
610
|
+
|
611
|
+
it "a higher priority contribution is selected when resolution is :priority" do
|
612
|
+
hash_of_duck = type_factory.hash_of(duck_type)
|
613
|
+
multibind_id = "ducks"
|
614
|
+
|
615
|
+
bindings.multibind(multibind_id).type(hash_of_duck).name('donalds_nephews')
|
616
|
+
|
617
|
+
mb1 = bindings.when_in_category("highest", "test").bind.in_multibind(multibind_id)
|
618
|
+
mb1.type(duck_type).name('nephew').to(InjectorSpecModule::NamedDuck, 'Huey')
|
619
|
+
|
620
|
+
mb2 = bindings.bind.in_multibind(multibind_id)
|
621
|
+
mb2.type(duck_type).name('nephew').to(InjectorSpecModule::NamedDuck, 'Dewey')
|
622
|
+
|
623
|
+
binder.define_categories(factory.categories(['highest', 'test']))
|
624
|
+
binder.define_layers(layered_bindings)
|
625
|
+
|
626
|
+
injector(binder).lookup(scope, hash_of_duck, "donalds_nephews")['nephew'].name.should == 'Huey'
|
627
|
+
end
|
628
|
+
|
629
|
+
it "a higher priority contribution wins when resolution is :merge" do
|
630
|
+
hash_of_data = type_factory.hash_of_data()
|
631
|
+
multibind_id = "hashed_ducks"
|
632
|
+
|
633
|
+
bindings.multibind(multibind_id).type(hash_of_data).name('donalds_nephews').producer_options(:conflict_resolution => :merge)
|
634
|
+
|
635
|
+
mb1 = bindings.when_in_category("highest", "test").bind.in_multibind(multibind_id)
|
636
|
+
mb1.name('nephew').to({'name' => 'Huey', 'is' => 'winner'})
|
637
|
+
|
638
|
+
mb2 = bindings.bind.in_multibind(multibind_id)
|
639
|
+
mb2.name('nephew').to({'name' => 'Dewey', 'is' => 'looser', 'has' => 'cap'})
|
640
|
+
|
641
|
+
binder.define_categories(factory.categories(['highest', 'test']))
|
642
|
+
binder.define_layers(layered_bindings)
|
643
|
+
|
644
|
+
the_ducks = injector(binder).lookup(scope, "donalds_nephews");
|
645
|
+
the_ducks['nephew']['name'].should == 'Huey'
|
646
|
+
the_ducks['nephew']['is'].should == 'winner'
|
647
|
+
the_ducks['nephew']['has'].should == 'cap'
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
context "of array kind" do
|
652
|
+
it "an array multibind produces contributed items, names are allowed but ignored" do
|
653
|
+
array_of_duck = type_factory.array_of(duck_type)
|
654
|
+
multibind_id = "ducks"
|
655
|
+
|
656
|
+
bindings.multibind(multibind_id).type(array_of_duck).name('donalds_nephews')
|
657
|
+
# one with name (ignored, expect no error)
|
658
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).name('nephew1').to(InjectorSpecModule::NamedDuck, 'Huey')
|
659
|
+
# two without name
|
660
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).to(InjectorSpecModule::NamedDuck, 'Dewey')
|
661
|
+
bindings.bind.in_multibind(multibind_id).type(duck_type).to(InjectorSpecModule::NamedDuck, 'Louie')
|
662
|
+
|
663
|
+
the_ducks = injector(lbinder).lookup(scope, array_of_duck, "donalds_nephews")
|
664
|
+
the_ducks.size.should == 3
|
665
|
+
the_ducks.collect {|d| d.name }.sort.should == ['Dewey', 'Huey', 'Louie']
|
666
|
+
end
|
667
|
+
|
668
|
+
it "should be able to make result contain only unique entries" do
|
669
|
+
# This case uses a multibind of individual strings, and combines them
|
670
|
+
# into an array of unique values
|
671
|
+
#
|
672
|
+
array_of_data = type_factory.array_of_data()
|
673
|
+
multibind_id = "ducks"
|
674
|
+
mb = bindings.multibind(multibind_id).type(array_of_data).name('donalds_family')
|
675
|
+
# turn off priority on named to not trigger conflict as all additions have the same precedence
|
676
|
+
# (could have used the default for unnamed and add unnamed entries).
|
677
|
+
mb.producer_options(:priority_on_named => false, :uniq => true)
|
678
|
+
|
679
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Huey')
|
680
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Dewey')
|
681
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Dewey') # duplicate
|
682
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Louie')
|
683
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Louie') # duplicate
|
684
|
+
bindings.bind.in_multibind(multibind_id).name('nephews').to('Louie') # duplicate
|
685
|
+
|
686
|
+
ducks = injector(lbinder).lookup(scope, 'donalds_family')
|
687
|
+
ducks.should == ['Huey', 'Dewey', 'Louie']
|
688
|
+
end
|
689
|
+
|
690
|
+
it "should be able to contribute elements and arrays of elements and flatten 1 level" do
|
691
|
+
# This case uses a multibind of individual strings and arrays, and combines them
|
692
|
+
# into an array of flattened
|
693
|
+
#
|
694
|
+
array_of_string = type_factory.array_of(type_factory.string())
|
695
|
+
|
696
|
+
multibind_id = "ducks"
|
697
|
+
mb = bindings.multibind(multibind_id).type(array_of_string).name('donalds_family')
|
698
|
+
# flatten one level
|
699
|
+
mb.producer_options(:flatten => 1)
|
700
|
+
|
701
|
+
bindings.bind.in_multibind(multibind_id).to('Huey')
|
702
|
+
bindings.bind.in_multibind(multibind_id).to('Dewey')
|
703
|
+
bindings.bind.in_multibind(multibind_id).to('Louie') # duplicate
|
704
|
+
bindings.bind.in_multibind(multibind_id).to(['Huey', 'Dewey', 'Louie'])
|
705
|
+
|
706
|
+
ducks = injector(lbinder).lookup(scope, 'donalds_family')
|
707
|
+
ducks.should == ['Huey', 'Dewey', 'Louie', 'Huey', 'Dewey', 'Louie']
|
708
|
+
end
|
709
|
+
|
710
|
+
it "should produce detailed type error message" do
|
711
|
+
array_of_integer = type_factory.array_of(type_factory.integer())
|
712
|
+
|
713
|
+
multibind_id = "ints"
|
714
|
+
mb = bindings.multibind(multibind_id).type(array_of_integer).name('donalds_family')
|
715
|
+
bindings.bind.in_multibind(multibind_id).to('Huey')
|
716
|
+
|
717
|
+
expect { ducks = injector(lbinder).lookup(scope, 'donalds_family')
|
718
|
+
}.to raise_error(%r{expected: Integer, or Array\[Integer\], got: String})
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
context "When using multibind in multibind" do
|
723
|
+
it "a hash multibind can be contributed to another" do
|
724
|
+
hash_of_data = type_factory.hash_of_data()
|
725
|
+
mb1_id = 'data1'
|
726
|
+
mb2_id = 'data2'
|
727
|
+
top = bindings.multibind(mb1_id).type(hash_of_data).name("top")
|
728
|
+
detail = bindings.multibind(mb2_id).type(hash_of_data).name("detail").in_multibind(mb1_id)
|
729
|
+
|
730
|
+
bindings.bind.in_multibind(mb1_id).name('a').to(10)
|
731
|
+
bindings.bind.in_multibind(mb1_id).name('b').to(20)
|
732
|
+
bindings.bind.in_multibind(mb2_id).name('a').to(30)
|
733
|
+
bindings.bind.in_multibind(mb2_id).name('b').to(40)
|
734
|
+
expect( injector(lbinder).lookup(scope, "top") ).to eql({'detail' => {'a' => 30, 'b' => 40}, 'a' => 10, 'b' => 20})
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
738
|
+
context "When looking up entries requiring evaluation" do
|
739
|
+
let(:node) { Puppet::Node.new('localhost') }
|
740
|
+
let(:compiler) { Puppet::Parser::Compiler.new(node)}
|
741
|
+
let(:scope) { Puppet::Parser::Scope.new(compiler) }
|
742
|
+
let(:parser) { Puppet::Pops::Parser::Parser.new() }
|
743
|
+
|
744
|
+
it "should be possible to lookup a concatenated string" do
|
745
|
+
scope['duck'] = 'Donald Fauntleroy Duck'
|
746
|
+
expr = parser.parse_string('"Hello $duck"').current()
|
747
|
+
bindings.bind.name('the_duck').to(expr)
|
748
|
+
injector(lbinder).lookup(scope, 'the_duck').should == 'Hello Donald Fauntleroy Duck'
|
749
|
+
end
|
750
|
+
|
751
|
+
it "should be possible to post process lookup with a puppet lambda" do
|
752
|
+
model = parser.parse_string('fake() |$value| {$value + 1 }').current
|
753
|
+
bindings.bind.name('an_int').to(42).producer_options( :transformer => model.lambda)
|
754
|
+
injector(lbinder).lookup(scope, 'an_int').should == 43
|
755
|
+
end
|
756
|
+
|
757
|
+
it "should be possible to post process lookup with a ruby proc" do
|
758
|
+
transformer = lambda {|scope, value| value + 1 }
|
759
|
+
bindings.bind.name('an_int').to(42).producer_options( :transformer => transformer)
|
760
|
+
injector(lbinder).lookup(scope, 'an_int').should == 43
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|
764
|
+
context "When there are problems with configuration" do
|
765
|
+
let(:binder) { binder_with_categories()}
|
766
|
+
let(:lbinder) { binder.define_layers(layered_bindings) }
|
767
|
+
|
768
|
+
it "reports error for surfacing abstract bindings" do
|
769
|
+
bindings.bind.abstract.name('an_int')
|
770
|
+
expect{injector(lbinder).lookup(scope, 'an_int') }.to raise_error(/The abstract binding .* was not overridden/)
|
771
|
+
end
|
772
|
+
|
773
|
+
it "does not report error for abstract binding that is ovrridden" do
|
774
|
+
bindings.bind.abstract.name('an_int')
|
775
|
+
bindings.when_in_category('highest', 'test').bind.override.name('an_int').to(142)
|
776
|
+
expect{injector(lbinder).lookup(scope, 'an_int') }.to_not raise_error
|
777
|
+
end
|
778
|
+
|
779
|
+
it "reports error for overriding binding that does not override" do
|
780
|
+
bindings.bind.override.name('an_int').to(42)
|
781
|
+
expect{injector(lbinder).lookup(scope, 'an_int') }.to raise_error(/Binding with unresolved 'override' detected/)
|
782
|
+
end
|
783
|
+
|
784
|
+
it "reports error for binding without producer" do
|
785
|
+
bindings.bind.name('an_int')
|
786
|
+
expect{injector(lbinder).lookup(scope, 'an_int') }.to raise_error(/Binding without producer/)
|
787
|
+
end
|
788
|
+
end
|
789
|
+
end
|