diff --git a/Rakefile b/Rakefile index e59d20ade..2cbe4a114 100644 --- a/Rakefile +++ b/Rakefile @@ -1,53 +1,47 @@ # Rakefile for Puppet -*- ruby -*- $LOAD_PATH << File.join(File.dirname(__FILE__), 'tasks') require 'rake' require 'rake/packagetask' require 'rake/gempackagetask' require 'rspec' require "rspec/core/rake_task" module Puppet PUPPETVERSION = File.read('lib/puppet.rb')[/PUPPETVERSION *= *'(.*)'/,1] or fail "Couldn't find PUPPETVERSION" end Dir['tasks/**/*.rake'].each { |t| load t } FILES = FileList[ '[A-Z]*', 'install.rb', 'bin/**/*', 'sbin/**/*', 'lib/**/*', 'conf/**/*', 'man/**/*', 'examples/**/*', 'ext/**/*', 'tasks/**/*', - 'test/**/*', 'spec/**/*' ] Rake::PackageTask.new("puppet", Puppet::PUPPETVERSION) do |pkg| pkg.package_dir = 'pkg' pkg.need_tar_gz = true pkg.package_files = FILES.to_a end task :default do sh %{rake -T} end desc "Create the tarball and the gem - use when releasing" task :puppetpackages => [:create_gem, :package] RSpec::Core::RakeTask.new do |t| t.pattern ='spec/{unit,integration}/**/*.rb' t.fail_on_error = true end - -desc "Run the unit tests" -task :unit do - Dir.chdir("test") { sh "rake" } -end diff --git a/acceptance/tests/resource/cron/should_not_rewrite_with_trailing_whitespace.rb b/acceptance/tests/resource/cron/should_not_rewrite_with_trailing_whitespace.rb new file mode 100644 index 000000000..26fb87b62 --- /dev/null +++ b/acceptance/tests/resource/cron/should_not_rewrite_with_trailing_whitespace.rb @@ -0,0 +1,40 @@ +test_name "should not rewrite if the job has trailing whitespace" + +tmpuser = "pl#{rand(999999).to_i}" +tmpfile = "/tmp/cron-test-#{Time.new.to_i}" + +create_user = "user { '#{tmpuser}': ensure => present, managehome => false }" +delete_user = "user { '#{tmpuser}': ensure => absent, managehome => false }" + +agents.each do |host| + if host['platform'].include?('windows') + skip_test "Test not supported on this platform" + next + end + + step "ensure the user exist via puppet" + apply_manifest_on host, create_user + + step "apply the resource on the host using puppet resource" + on(host, puppet_resource("cron", "crontest", "user=#{tmpuser}", + "command='date > /dev/null '", "ensure=present")) do + assert_match(/created/, stdout, "Did not create crontab for #{tmpuser} on #{host}") + end + + step "verify that crontab -l contains what you expected" + run_cron_on(host, :list, tmpuser) do + assert_match(/\* \* \* \* \* date > .dev.null /, stdout, "Incorrect crontab for #{tmpuser} on #{host}") + end + + step "apply the resource again on the host using puppet resource and check nothing happened" + on(host, puppet_resource("cron", "crontest", "user=#{tmpuser}", + "command='date > /dev/null '", "ensure=present")) do + assert_no_match(/ensure: created/, stdout, "Rewrote the line with trailing space in crontab for #{tmpuser} on #{host}") + end + + step "remove the crontab file for that user" + run_cron_on(host, :remove, tmpuser) + + step "remove the user from the system" + apply_manifest_on host, delete_user +end diff --git a/lib/puppet/application/doc.rb b/lib/puppet/application/doc.rb index 1a80823dd..a368ffdc8 100644 --- a/lib/puppet/application/doc.rb +++ b/lib/puppet/application/doc.rb @@ -1,272 +1,279 @@ require 'puppet/application' class Puppet::Application::Doc < Puppet::Application run_mode :master attr_accessor :unknown_args, :manifest def preinit {:references => [], :mode => :text, :format => :to_markdown }.each do |name,value| options[name] = value end @unknown_args = [] @manifest = false end option("--all","-a") option("--outputdir OUTPUTDIR","-o") option("--verbose","-v") option("--debug","-d") option("--charset CHARSET") option("--format FORMAT", "-f") do |arg| method = "to_#{arg}" require 'puppet/util/reference' if Puppet::Util::Reference.method_defined?(method) options[:format] = method else raise "Invalid output format #{arg}" end end option("--mode MODE", "-m") do |arg| require 'puppet/util/reference' if Puppet::Util::Reference.modes.include?(arg) or arg.intern==:rdoc options[:mode] = arg.intern else raise "Invalid output mode #{arg}" end end option("--list", "-l") do |arg| require 'puppet/util/reference' puts Puppet::Util::Reference.references.collect { |r| Puppet::Util::Reference.reference(r).doc }.join("\n") exit(0) end option("--reference REFERENCE", "-r") do |arg| options[:references] << arg.intern end def help <<-HELP puppet-doc(8) -- Generate Puppet documentation and references ======== SYNOPSIS -------- Generates a reference for all Puppet types. Largely meant for internal Puppet Labs use. +WARNING: RDoc support is only available under Ruby 1.8.7 and earlier. + USAGE ----- puppet doc [-a|--all] [-h|--help] [-o|--outputdir ] [-m|--mode text|pdf|rdoc] [-r|--reference ] [--charset ] [] DESCRIPTION ----------- If mode is not 'rdoc', then this command generates a Markdown document describing all installed Puppet types or all allowable arguments to puppet executables. It is largely meant for internal use and is used to generate the reference document available on the Puppet Labs web site. In 'rdoc' mode, this command generates an html RDoc hierarchy describing the manifests that are in 'manifestdir' and 'modulepath' configuration directives. The generated documentation directory is doc by default but can be changed with the 'outputdir' option. If the command is run with the name of a manifest file as an argument, puppet doc will output a single manifest's documentation on stdout. +WARNING: RDoc support is only available under Ruby 1.8.7 and earlier. +The internal API used to support manifest documentation has changed +radically in newer versions, and support is not yet available for +using those versions of RDoc. + OPTIONS ------- * --all: Output the docs for all of the reference types. In 'rdoc' mode, this also outputs documentation for all resources. * --help: Print this help message * --outputdir: Used only in 'rdoc' mode. The directory to which the rdoc output should be written. * --mode: Determine the output mode. Valid modes are 'text', 'pdf' and 'rdoc'. The 'pdf' mode creates PDF formatted files in the /tmp directory. The default mode is 'text'. In 'rdoc' mode you must provide 'manifests-path' * --reference: Build a particular reference. Get a list of references by running 'puppet doc --list'. * --charset: Used only in 'rdoc' mode. It sets the charset used in the html files produced. * --manifestdir: Used only in 'rdoc' mode. The directory to scan for stand-alone manifests. If not supplied, puppet doc will use the manifestdir from puppet.conf. * --modulepath: Used only in 'rdoc' mode. The directory or directories to scan for modules. If not supplied, puppet doc will use the modulepath from puppet.conf. * --environment: Used only in 'rdoc' mode. The configuration environment from which to read the modulepath and manifestdir settings, when reading said settings from puppet.conf. Due to a known bug, this option is not currently effective. EXAMPLE ------- $ puppet doc -r type > /tmp/type_reference.markdown or $ puppet doc --outputdir /tmp/rdoc --mode rdoc /path/to/manifests or $ puppet doc /etc/puppet/manifests/site.pp or $ puppet doc -m pdf -r configuration AUTHOR ------ Luke Kanies COPYRIGHT --------- Copyright (c) 2011 Puppet Labs, LLC Licensed under the Apache 2.0 License HELP end def handle_unknown( opt, arg ) @unknown_args << {:opt => opt, :arg => arg } true end def run_command return[:rdoc].include?(options[:mode]) ? send(options[:mode]) : other end def rdoc exit_code = 0 files = [] unless @manifest env = Puppet::Node::Environment.new files += env.modulepath files << ::File.dirname(env[:manifest]) end files += command_line.args Puppet.info "scanning: #{files.inspect}" Puppet.settings[:document_all] = options[:all] || false begin require 'puppet/util/rdoc' if @manifest Puppet::Util::RDoc.manifestdoc(files) else options[:outputdir] = "doc" unless options[:outputdir] Puppet::Util::RDoc.rdoc(options[:outputdir], files, options[:charset]) end rescue => detail Puppet.log_exception(detail, "Could not generate documentation: #{detail}") exit_code = 1 end exit exit_code end def other text = "" with_contents = options[:references].length <= 1 exit_code = 0 require 'puppet/util/reference' options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name| raise "Could not find reference #{name}" unless section = Puppet::Util::Reference.reference(name) begin # Add the per-section text, but with no ToC text += section.send(options[:format], with_contents) rescue => detail Puppet.log_exception(detail, "Could not generate reference #{name}: #{detail}") exit_code = 1 next end end text += Puppet::Util::Reference.footer unless with_contents # We've only got one reference if options[:mode] == :pdf Puppet::Util::Reference.pdf(text) else puts text end exit exit_code end def setup # sole manifest documentation if command_line.args.size > 0 options[:mode] = :rdoc @manifest = true end if options[:mode] == :rdoc setup_rdoc else setup_reference end end def setup_reference if options[:all] # Don't add dynamic references to the "all" list. require 'puppet/util/reference' options[:references] = Puppet::Util::Reference.references.reject do |ref| Puppet::Util::Reference.reference(ref).dynamic? end end options[:references] << :type if options[:references].empty? end def setup_rdoc(dummy_argument=:work_arround_for_ruby_GC_bug) # consume the unknown options # and feed them as settings if @unknown_args.size > 0 @unknown_args.each do |option| # force absolute path for modulepath when passed on commandline if option[:opt]=="--modulepath" or option[:opt] == "--manifestdir" option[:arg] = option[:arg].split(::File::PATH_SEPARATOR).collect { |p| ::File.expand_path(p) }.join(::File::PATH_SEPARATOR) end Puppet.settings.handlearg(option[:opt], option[:arg]) end end # Now parse the config Puppet.parse_config # Handle the logging settings. if options[:debug] or options[:verbose] if options[:debug] Puppet::Util::Log.level = :debug else Puppet::Util::Log.level = :info end Puppet::Util::Log.newdestination(:console) end end end diff --git a/lib/puppet/application/face_base.rb b/lib/puppet/application/face_base.rb index a80ca5437..b8ecc9c00 100644 --- a/lib/puppet/application/face_base.rb +++ b/lib/puppet/application/face_base.rb @@ -1,265 +1,265 @@ require 'puppet/application' require 'puppet/face' require 'optparse' require 'pp' class Puppet::Application::FaceBase < Puppet::Application run_mode :agent option("--debug", "-d") do |arg| Puppet::Util::Log.level = :debug end - option("--verbose", "-v") do + option("--verbose", "-v") do |_| Puppet::Util::Log.level = :info end option("--render-as FORMAT") do |format| self.render_as = format.to_sym end # This seems like a bad thing; it seems like--in an ideal world--a given app/face should have one constant run mode. # This isn't currently possible because of issues relating to the certificate authority, but I've left some notes # about "run_mode" in settings.rb and defaults.rb, and if we are able to tighten up the behavior / implementation # of that setting, we might want to revisit this. --cprice 2012-03-16 option("--mode RUNMODE", "-r") do |arg| raise "Invalid run mode #{arg}; supported modes are user, agent, master" unless %w{user agent master}.include?(arg) self.class.run_mode(arg.to_sym) end attr_accessor :face, :action, :type, :arguments, :render_as def render_as=(format) if format == :json then @render_as = Puppet::Network::FormatHandler.format(:pson) else @render_as = Puppet::Network::FormatHandler.format(format) end @render_as or raise ArgumentError, "I don't know how to render '#{format}'" end def render(result, args_and_options) hook = action.when_rendering(render_as.name) if hook # when defining when_rendering on your action you can optionally # include arguments and options if hook.arity > 1 result = hook.call(result, *args_and_options) else result = hook.call(result) end end render_as.render(result) end def preinit super Signal.trap(:INT) do $stderr.puts "Cancelling Face" exit(0) end end def parse_options # We need to parse enough of the command line out early, to identify what # the action is, so that we can obtain the full set of options to parse. # REVISIT: These should be configurable versions, through a global # '--version' option, but we don't implement that yet... --daniel 2011-03-29 @type = self.class.name.to_s.sub(/.+:/, '').downcase.to_sym @face = Puppet::Face[@type, :current] # Now, walk the command line and identify the action. We skip over # arguments based on introspecting the action and all, and find the first # non-option word to use as the action. action_name = nil index = -1 until action_name or (index += 1) >= command_line.args.length do item = command_line.args[index] if item =~ /^-/ then option = @face.options.find do |name| item =~ /^-+#{name.to_s.gsub(/[-_]/, '[-_]')}(?:[ =].*)?$/ end if option then option = @face.get_option(option) # If we have an inline argument, just carry on. We don't need to # care about optional vs mandatory in that case because we do a real # parse later, and that will totally take care of raising the error # when we get there. --daniel 2011-04-04 if option.takes_argument? and !item.index('=') then index += 1 unless (option.optional_argument? and command_line.args[index + 1] =~ /^-/) end elsif option = find_global_settings_argument(item) then unless Puppet.settings.boolean? option.name then # As far as I can tell, we treat non-bool options as always having # a mandatory argument. --daniel 2011-04-05 index += 1 # ...so skip the argument. end elsif option = find_application_argument(item) then index += 1 if (option[:argument] and not option[:optional]) else raise OptionParser::InvalidOption.new(item.sub(/=.*$/, '')) end else # Stash away the requested action name for later, and try to fetch the # action object it represents; if this is an invalid action name that # will be nil, and handled later. action_name = item.to_sym @action = Puppet::Face.find_action(@face.name, action_name) @face = @action.face if @action end end if @action.nil? if @action = @face.get_default_action() then @is_default_action = true else # REVISIT: ...and this horror thanks to our log setup, which doesn't # initialize destinations until the setup method, which we will never # reach. We could also just print here, but that is actually a little # uglier and nastier in the long term, in which we should do log setup # earlier if at all possible. --daniel 2011-05-31 Puppet::Util::Log.newdestination(:console) face = @face.name action = action_name.nil? ? 'default' : "'#{action_name}'" msg = "'#{face}' has no #{action} action. See `puppet help #{face}`." Puppet.err(msg) exit false end end # Now we can interact with the default option code to build behaviour # around the full set of options we now know we support. @action.options.each do |option| option = @action.get_option(option) # make it the object. self.class.option(*option.optparse) # ...and make the CLI parse it. end # ...and invoke our parent to parse all the command line options. super end def find_global_settings_argument(item) Puppet.settings.each do |name, object| object.optparse_args.each do |arg| next unless arg =~ /^-/ # sadly, we have to emulate some of optparse here... pattern = /^#{arg.sub('[no-]', '').sub(/[ =].*$/, '')}(?:[ =].*)?$/ pattern.match item and return object end end return nil # nothing found. end def find_application_argument(item) self.class.option_parser_commands.each do |options, function| options.each do |option| next unless option =~ /^-/ pattern = /^#{option.sub('[no-]', '').sub(/[ =].*$/, '')}(?:[ =].*)?$/ next unless pattern.match(item) return { :argument => option =~ /[ =]/, :optional => option =~ /[ =]\[/ } end end return nil # not found end def setup Puppet::Util::Log.newdestination :console @arguments = command_line.args # Note: because of our definition of where the action is set, we end up # with it *always* being the first word of the remaining set of command # line arguments. So, strip that off when we construct the arguments to # pass down to the face action. --daniel 2011-04-04 # Of course, now that we have default actions, we should leave the # "action" name on if we didn't actually consume it when we found our # action. @arguments.delete_at(0) unless @is_default_action # We copy all of the app options to the end of the call; This allows each # action to read in the options. This replaces the older model where we # would invoke the action with options set as global state in the # interface object. --daniel 2011-03-28 @arguments << options # If we don't have a rendering format, set one early. self.render_as ||= (@action.render_as || :console) end def main status = false # Call the method associated with the provided action (e.g., 'find'). unless @action puts Puppet::Face[:help, :current].help(@face.name) raise "#{face} does not respond to action #{arguments.first}" end # We need to do arity checking here because this is generic code # calling generic methods – that have argument defaulting. We need to # make sure we don't accidentally pass the options as the first # argument to a method that takes one argument. eg: # # puppet facts find # => options => {} # @arguments => [{}] # => @face.send :bar, {} # # def face.bar(argument, options = {}) # => bar({}, {}) # oops! we thought the options were the # # positional argument!! # # We could also fix this by making it mandatory to pass the options on # every call, but that would make the Ruby API much more annoying to # work with; having the defaulting is a much nicer convention to have. # # We could also pass the arguments implicitly, by having a magic # 'options' method that was visible in the scope of the action, which # returned the right stuff. # # That sounds attractive, but adds complications to all sorts of # things, especially when you think about how to pass options when you # are writing Ruby code that calls multiple faces. Especially if # faces are involved in that. ;) # # --daniel 2011-04-27 if (arity = @action.positional_arg_count) > 0 unless (count = arguments.length) == arity then s = arity == 2 ? '' : 's' raise ArgumentError, "puppet #{@face.name} #{@action.name} takes #{arity-1} argument#{s}, but you gave #{count-1}" end end result = @face.send(@action.name, *arguments) puts render(result, arguments) unless result.nil? status = true # We need an easy way for the action to set a specific exit code, so we # rescue SystemExit here; This allows each action to set the desired exit # code by simply calling Kernel::exit. eg: # # exit(2) # # --kelsey 2012-02-14 rescue SystemExit => detail status = detail.status rescue Exception => detail Puppet.log_exception(detail) Puppet.err "Try 'puppet help #{@face.name} #{@action.name}' for usage" ensure exit status end end diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb index 22e8f9725..a6058b82f 100644 --- a/lib/puppet/configurer.rb +++ b/lib/puppet/configurer.rb @@ -1,258 +1,257 @@ # The client for interacting with the puppetmaster config server. require 'sync' require 'timeout' require 'puppet/network/http_pool' require 'puppet/util' class Puppet::Configurer require 'puppet/configurer/fact_handler' require 'puppet/configurer/plugin_handler' include Puppet::Configurer::FactHandler include Puppet::Configurer::PluginHandler # For benchmarking include Puppet::Util attr_reader :compile_time # Provide more helpful strings to the logging that the Agent does def self.to_s "Puppet configuration client" end class << self # Puppetd should only have one instance running, and we need a way # to retrieve it. attr_accessor :instance include Puppet::Util end # How to lock instances of this class. def self.lockfile_path Puppet[:puppetdlockfile] end def execute_postrun_command execute_from_setting(:postrun_command) end def execute_prerun_command execute_from_setting(:prerun_command) end # Initialize and load storage def dostorage Puppet::Util::Storage.load @compile_time ||= Puppet::Util::Storage.cache(:configuration)[:compile_time] rescue => detail Puppet.log_exception(detail, "Removing corrupt state file #{Puppet[:statefile]}: #{detail}") begin ::File.unlink(Puppet[:statefile]) retry rescue => detail raise Puppet::Error.new("Cannot remove #{Puppet[:statefile]}: #{detail}") end end # Just so we can specify that we are "the" instance. def initialize Puppet.settings.use(:main, :ssl, :agent) self.class.instance = self @running = false @splayed = false end # Prepare for catalog retrieval. Downloads everything necessary, etc. def prepare(options) dostorage download_plugins unless options[:skip_plugin_download] end # Get the remote catalog, yo. Returns nil if no catalog can be found. def retrieve_catalog(fact_options) fact_options ||= {} # First try it with no cache, then with the cache. unless (Puppet[:use_cached_catalog] and result = retrieve_catalog_from_cache(fact_options)) or result = retrieve_new_catalog(fact_options) if ! Puppet[:usecacheonfailure] Puppet.warning "Not using cache on failed catalog" return nil end result = retrieve_catalog_from_cache(fact_options) end return nil unless result convert_catalog(result, @duration) end # Convert a plain resource catalog into our full host catalog. def convert_catalog(result, duration) catalog = result.to_ral catalog.finalize catalog.retrieval_duration = duration catalog.write_class_file catalog.write_resource_file catalog end def prepare_and_retrieve_catalog(options) prepare(options) if Puppet::Resource::Catalog.indirection.terminus_class == :rest # This is a bit complicated. We need the serialized and escaped facts, # and we need to know which format they're encoded in. Thus, we # get a hash with both of these pieces of information. fact_options = facts_for_uploading end # set report host name now that we have the fact options[:report].host = Puppet[:node_name_value] unless catalog = (options.delete(:catalog) || retrieve_catalog(fact_options)) Puppet.err "Could not retrieve catalog; skipping run" return end catalog end # Retrieve (optionally) and apply a catalog. If a catalog is passed in # the options, then apply that one, otherwise retrieve it. def apply_catalog(catalog, options) report = options[:report] report.configuration_version = catalog.version report.environment = Puppet[:environment] benchmark(:notice, "Finished catalog run") do catalog.apply(options) end report.finalize_report report end # The code that actually runs the catalog. # This just passes any options on to the catalog, # which accepts :tags and :ignoreschedules. def run(options = {}) options[:report] ||= Puppet::Transaction::Report.new("apply") report = options[:report] Puppet::Util::Log.newdestination(report) begin begin unless catalog = prepare_and_retrieve_catalog(options) return nil end # Here we set the local environment based on what we get from the # catalog. Since a change in environment means a change in facts, and # facts may be used to determine which catalog we get, we need to # rerun the process if the environment is changed. tries = 0 while catalog.environment and not catalog.environment.empty? and catalog.environment != Puppet[:environment] if tries > 3 raise Puppet::Error, "Catalog environment didn't stabilize after #{tries} fetches, aborting run" end Puppet.warning "Local environment: \"#{Puppet[:environment]}\" doesn't match server specified environment \"#{catalog.environment}\", restarting agent run with new environment" Puppet[:environment] = catalog.environment return nil unless catalog = prepare_and_retrieve_catalog(options) tries += 1 end execute_prerun_command or return nil apply_catalog(catalog, options) report.exit_status rescue SystemExit,NoMemoryError raise rescue => detail Puppet.log_exception(detail, "Failed to apply catalog: #{detail}") return nil ensure execute_postrun_command or return nil end ensure # Make sure we forget the retained module_directories of any autoload # we might have used. Thread.current[:env_module_directories] = nil end ensure Puppet::Util::Log.close(report) send_report(report) end def send_report(report) puts report.summary if Puppet[:summarize] save_last_run_summary(report) Puppet::Transaction::Report.indirection.save(report) if Puppet[:report] rescue => detail Puppet.log_exception(detail, "Could not send report: #{detail}") end def save_last_run_summary(report) mode = Puppet.settings.setting(:lastrunfile).mode - Puppet::Util::FileLocking.writelock(Puppet[:lastrunfile]) do |file| - file.chmod(mode) - file.print YAML.dump(report.raw_summary) + Puppet::Util.replace_file(Puppet[:lastrunfile], mode) do |fh| + fh.print YAML.dump(report.raw_summary) end rescue => detail Puppet.log_exception(detail, "Could not save last run local report: #{detail}") end private def self.timeout timeout = Puppet[:configtimeout] case timeout when String if timeout =~ /^\d+$/ timeout = Integer(timeout) else raise ArgumentError, "Configuration timeout must be an integer" end when Integer # nothing else raise ArgumentError, "Configuration timeout must be an integer" end timeout end def execute_from_setting(setting) return true if (command = Puppet[setting]) == "" begin Puppet::Util::Execution.execute([command]) true rescue => detail Puppet.log_exception(detail, "Could not run command from #{setting}: #{detail}") false end end def retrieve_catalog_from_cache(fact_options) result = nil @duration = thinmark do result = Puppet::Resource::Catalog.indirection.find(Puppet[:node_name_value], fact_options.merge(:ignore_terminus => true)) end Puppet.notice "Using cached catalog" result rescue => detail Puppet.log_exception(detail, "Could not retrieve catalog from cache: #{detail}") return nil end def retrieve_new_catalog(fact_options) result = nil @duration = thinmark do result = Puppet::Resource::Catalog.indirection.find(Puppet[:node_name_value], fact_options.merge(:ignore_cache => true)) end result rescue SystemExit,NoMemoryError raise rescue Exception => detail Puppet.log_exception(detail, "Could not retrieve catalog from remote server: #{detail}") return nil end end diff --git a/lib/puppet/feature/rdoc1.rb b/lib/puppet/feature/rdoc1.rb new file mode 100644 index 000000000..a7e65c229 --- /dev/null +++ b/lib/puppet/feature/rdoc1.rb @@ -0,0 +1,16 @@ +require 'puppet/util/feature' + +# We have a version of RDoc compatible with our module documentation tool. +# That is to say, we have the version that comes with Ruby 1.8.7 and earlier, +# and not the version that comes with Ruby 1.9.1 or later. +# +# 1.8 => require 'rdoc/rdoc'; p RDoc::RDoc::VERSION_STRING +# => "RDoc V1.0.1 - 20041108" +# 1.9 => require 'rdoc'; p RDoc::VERSION +# => "3.9.4" # 1.9.2 has 2.5, 1.9.3 has 3.9 +# +# Anything above that whole 1.0.1 thing is no good for us, and since that +# ships with anything in the 1.8 series that we care about (eg: .5, ,7) we can +# totally just use that as a proxy for the correct version of rdoc being +# available. --daniel 2012-03-08 +Puppet.features.add(:rdoc1) { RUBY_VERSION[0,3] == "1.8" } diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb index 7cfabb80b..c2e28391a 100644 --- a/lib/puppet/indirector/yaml.rb +++ b/lib/puppet/indirector/yaml.rb @@ -1,75 +1,81 @@ require 'puppet/indirector/terminus' -require 'puppet/util/file_locking' # The base class for YAML indirection termini. class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus - include Puppet::Util::FileLocking + if defined?(::Psych::SyntaxError) + YamlLoadExceptions = [::StandardError, ::ArgumentError, ::Psych::SyntaxError] + else + YamlLoadExceptions = [::StandardError, ::ArgumentError] + end # Read a given name's file in and convert it from YAML. def find(request) file = path(request.key) return nil unless FileTest.exist?(file) yaml = nil begin - readlock(file) { |fh| yaml = fh.read } + yaml = ::File.read(file) rescue => detail raise Puppet::Error, "Could not read YAML data for #{indirection.name} #{request.key}: #{detail}" end + begin return from_yaml(yaml) - rescue => detail + rescue *YamlLoadExceptions => detail raise Puppet::Error, "Could not parse YAML data for #{indirection.name} #{request.key}: #{detail}" end end # Convert our object to YAML and store it to the disk. def save(request) raise ArgumentError.new("You can only save objects that respond to :name") unless request.instance.respond_to?(:name) file = path(request.key) basedir = File.dirname(file) # This is quite likely a bad idea, since we're not managing ownership or modes. Dir.mkdir(basedir) unless FileTest.exist?(basedir) begin - writelock(file, 0660) { |f| f.print to_yaml(request.instance) } + Puppet::Util.replace_file(file, 0660) do |f| + f.print to_yaml(request.instance) + end rescue TypeError => detail Puppet.err "Could not save #{self.name} #{request.key}: #{detail}" end end # Return the path to a given node's file. def path(name,ext='.yaml') if name =~ Puppet::Indirector::BadNameRegexp then Puppet.crit("directory traversal detected in #{self.class}: #{name.inspect}") raise ArgumentError, "invalid key" end base = Puppet.run_mode.master? ? Puppet[:yamldir] : Puppet[:clientyamldir] File.join(base, self.class.indirection_name.to_s, name.to_s + ext) end def destroy(request) file_path = path(request.key) File.unlink(file_path) if File.exists?(file_path) end def search(request) Dir.glob(path(request.key,'')).collect do |file| YAML.load_file(file) end end private def from_yaml(text) YAML.load(text) end def to_yaml(object) YAML.dump(object) end end diff --git a/lib/puppet/network/http/mongrel.rb b/lib/puppet/network/http/mongrel.rb index ee103b550..a13a98b21 100644 --- a/lib/puppet/network/http/mongrel.rb +++ b/lib/puppet/network/http/mongrel.rb @@ -1,32 +1,35 @@ require 'mongrel' if Puppet.features.mongrel? require 'puppet/network/http/mongrel/rest' class Puppet::Network::HTTP::Mongrel def initialize(args = {}) @listening = false end def listen(args = {}) raise ArgumentError, ":address must be specified." unless args[:address] raise ArgumentError, ":port must be specified." unless args[:port] raise "Mongrel server is already listening" if listening? @server = Mongrel::HttpServer.new(args[:address], args[:port]) @server.register('/', Puppet::Network::HTTP::MongrelREST.new(:server => @server)) @listening = true @server.run end def unlisten raise "Mongrel server is not listening" unless listening? - @server.stop + # We wait until the running process has terminated, rather than letting + # the shutdown happen in the background. This might delay exit, but is + # nicer than the alternative of killing something horribly. --daniel 2012-03-12 + @server.stop(true) @server = nil @listening = false end def listening? @listening end end diff --git a/lib/puppet/parser/ast/selector.rb b/lib/puppet/parser/ast/selector.rb index d6a4ea436..04f0b1873 100644 --- a/lib/puppet/parser/ast/selector.rb +++ b/lib/puppet/parser/ast/selector.rb @@ -1,44 +1,50 @@ require 'puppet/parser/ast/branch' class Puppet::Parser::AST # The inline conditional operator. Unlike CaseStatement, which executes # code, we just return a value. class Selector < AST::Branch attr_accessor :param, :values def each [@param,@values].each { |child| yield child } end # Find the value that corresponds with the test. def evaluate(scope) level = scope.ephemeral_level # Get our parameter. paramvalue = @param.safeevaluate(scope) default = nil @values = [@values] unless @values.instance_of? AST::ASTArray or @values.instance_of? Array # Then look for a match in the options. @values.each do |obj| # short circuit asap if we have a match return obj.value.safeevaluate(scope) if obj.param.evaluate_match(paramvalue, scope) # Store the default, in case it's necessary. default = obj if obj.param.is_a?(Default) end # Unless we found something, look for the default. return default.value.safeevaluate(scope) if default self.fail Puppet::ParseError, "No matching value for selector param '#{paramvalue}'" ensure scope.unset_ephemeral_var(level) end def to_s - param.to_s + " ? { " + values.collect { |v| v.to_s }.join(', ') + " }" + if @values.instance_of? AST::ASTArray or @values.instance_of? Array + v = @values + else + v = [@values] + end + + param.to_s + " ? { " + v.collect { |v| v.to_s }.join(', ') + " }" end end end diff --git a/lib/puppet/parser/functions/shellquote.rb b/lib/puppet/parser/functions/shellquote.rb index ee070c740..d44dc2b80 100644 --- a/lib/puppet/parser/functions/shellquote.rb +++ b/lib/puppet/parser/functions/shellquote.rb @@ -1,65 +1,69 @@ # Copyright (C) 2009 Thomas Bellman # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THOMAS BELLMAN BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of Thomas Bellman shall # not be used in advertising or otherwise to promote the sale, use or # other dealings in this Software without prior written authorization # from Thomas Bellman. module Puppet::Parser::Functions Safe = 'a-zA-Z0-9@%_+=:,./-' # Safe unquoted Dangerous = '!"`$\\' # Unsafe inside double quotes newfunction(:shellquote, :type => :rvalue, :doc => "\ Quote and concatenate arguments for use in Bourne shell. Each argument is quoted separately, and then all are concatenated with spaces. If an argument is an array, the elements of that array is interpolated within the rest of the arguments; this makes it possible to have an array of arguments and pass that array to shellquote instead of having to specify each argument individually in the call. ") \ do |args| result = [] args.flatten.each do |word| if word.length != 0 and word.count(Safe) == word.length result << word elsif word.count(Dangerous) == 0 result << ('"' + word + '"') elsif word.count("'") == 0 result << ("'" + word + "'") else r = '"' + # We want each byte, because that is how sh will process it in enough + # cases; Ruby 1.8.5 ends up making this the way that gets expressed, + # because it requires a block to the `each_byte` method. word.each_byte do |c| + c = c.chr r += "\\" if Dangerous.include?(c) - r += c.chr + r += c end r += '"' result << r end end return result.join(" ") end end diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb index 2edbcd829..ee1a8c436 100644 --- a/lib/puppet/parser/resource.rb +++ b/lib/puppet/parser/resource.rb @@ -1,335 +1,336 @@ require 'puppet/resource' # The primary difference between this class and its # parent is that this class has rules on who can set # parameters class Puppet::Parser::Resource < Puppet::Resource require 'puppet/parser/resource/param' require 'puppet/util/tagging' require 'puppet/file_collection/lookup' require 'puppet/parser/yaml_trimmer' require 'puppet/resource/type_collection_helper' include Puppet::FileCollection::Lookup include Puppet::Resource::TypeCollectionHelper include Puppet::Util include Puppet::Util::MethodHelper include Puppet::Util::Errors include Puppet::Util::Logging include Puppet::Util::Tagging include Puppet::Parser::YamlTrimmer attr_accessor :source, :scope, :collector_id attr_accessor :virtual, :override, :translated, :catalog, :evaluated attr_reader :exported, :parameters # Determine whether the provided parameter name is a relationship parameter. def self.relationship_parameter?(name) @relationship_names ||= Puppet::Type.relationship_params.collect { |p| p.name } @relationship_names.include?(name) end # Set up some boolean test methods def translated?; !!@translated; end def override?; !!@override; end def evaluated?; !!@evaluated; end def [](param) param = symbolize(param) if param == :title return self.title end if @parameters.has_key?(param) @parameters[param].value else nil end end def []=(param, value) set_parameter(param, value) end def eachparam @parameters.each do |name, param| yield param end end def environment scope.environment end # Process the stage metaparameter for a class. A containment edge # is drawn from the class to the stage. The stage for containment # defaults to main, if none is specified. def add_edge_to_stage return unless self.type.to_s.downcase == "class" unless stage = catalog.resource(:stage, self[:stage] || (scope && scope.resource && scope.resource[:stage]) || :main) raise ArgumentError, "Could not find stage #{self[:stage] || :main} specified by #{self}" end self[:stage] ||= stage.title unless stage.title == :main catalog.add_edge(stage, self) end # Retrieve the associated definition and evaluate it. def evaluate return if evaluated? @evaluated = true if klass = resource_type and ! builtin_type? finish evaluated_code = klass.evaluate_code(self) return evaluated_code elsif builtin? devfail "Cannot evaluate a builtin type (#{type})" else self.fail "Cannot find definition #{type}" end end # Mark this resource as both exported and virtual, # or remove the exported mark. def exported=(value) if value @virtual = true @exported = value else @exported = value end end # Do any finishing work on this object, called before evaluation or # before storage/translation. def finish return if finished? @finished = true add_defaults add_metaparams add_scope_tags validate end # Has this resource already been finished? def finished? @finished end def initialize(*args) + raise ArgumentError, "Resources require a hash as last argument" unless args.last.is_a? Hash raise ArgumentError, "Resources require a scope" unless args.last[:scope] super @source ||= scope.source end # Is this resource modeling an isomorphic resource type? def isomorphic? if builtin_type? return resource_type.isomorphic? else return true end end # Merge an override resource in. This will throw exceptions if # any overrides aren't allowed. def merge(resource) # Test the resource scope, to make sure the resource is even allowed # to override. unless self.source.object_id == resource.source.object_id || resource.source.child_of?(self.source) raise Puppet::ParseError.new("Only subclasses can override parameters", resource.line, resource.file) end # Some of these might fail, but they'll fail in the way we want. resource.parameters.each do |name, param| override_parameter(param) end end # Unless we're running >= 0.25, we're in compat mode. def metaparam_compatibility_mode? ! (catalog and ver = (catalog.client_version||'0.0.0').split(".") and (ver[0] > "0" or ver[1].to_i >= 25)) end def name self[:name] || self.title end # A temporary occasion, until I get paths in the scopes figured out. def path to_s end # Define a parameter in our resource. # if we ever receive a parameter named 'tag', set # the resource tags with its value. def set_parameter(param, value = nil) if ! value.nil? param = Puppet::Parser::Resource::Param.new( :name => param, :value => value, :source => self.source ) elsif ! param.is_a?(Puppet::Parser::Resource::Param) raise ArgumentError, "Received incomplete information - no value provided for parameter #{param}" end tag(*param.value) if param.name == :tag # And store it in our parameter hash. @parameters[param.name] = param end def to_hash @parameters.inject({}) do |hash, ary| param = ary[1] # Skip "undef" values. hash[param.name] = param.value if param.value != :undef hash end end # Create a Puppet::Resource instance from this parser resource. # We plan, at some point, on not needing to do this conversion, but # it's sufficient for now. def to_resource result = Puppet::Resource.new(type, title) to_hash.each do |p, v| if v.is_a?(Puppet::Resource) v = Puppet::Resource.new(v.type, v.title) elsif v.is_a?(Array) # flatten resource references arrays v = v.flatten if v.flatten.find { |av| av.is_a?(Puppet::Resource) } v = v.collect do |av| av = Puppet::Resource.new(av.type, av.title) if av.is_a?(Puppet::Resource) av end end # If the value is an array with only one value, then # convert it to a single value. This is largely so that # the database interaction doesn't have to worry about # whether it returns an array or a string. result[p] = if v.is_a?(Array) and v.length == 1 v[0] else v end end result.file = self.file result.line = self.line result.exported = self.exported result.virtual = self.virtual result.tag(*self.tags) result end # Convert this resource to a RAL resource. def to_ral to_resource.to_ral end private # Add default values from our definition. def add_defaults scope.lookupdefaults(self.type).each do |name, param| unless @parameters.include?(name) self.debug "Adding default for #{name}" @parameters[name] = param.dup end end end def add_backward_compatible_relationship_param(name) # Skip metaparams for which we get no value. return unless scope.include?(name.to_s) val = scope[name.to_s] # The default case: just set the value set_parameter(name, val) and return unless @parameters[name] # For relationship params, though, join the values (a la #446). @parameters[name].value = [@parameters[name].value, val].flatten end # Add any metaparams defined in our scope. This actually adds any metaparams # from any parent scope, and there's currently no way to turn that off. def add_metaparams compat_mode = metaparam_compatibility_mode? Puppet::Type.eachmetaparam do |name| next unless self.class.relationship_parameter?(name) add_backward_compatible_relationship_param(name) if compat_mode end end def add_scope_tags if scope_resource = scope.resource tag(*scope_resource.tags) end end # Accept a parameter from an override. def override_parameter(param) # This can happen if the override is defining a new parameter, rather # than replacing an existing one. (set_parameter(param) and return) unless current = @parameters[param.name] # The parameter is already set. Fail if they're not allowed to override it. unless param.source.child_of?(current.source) msg = "Parameter '#{param.name}' is already set on #{self}" msg += " by #{current.source}" if current.source.to_s != "" if current.file or current.line fields = [] fields << current.file if current.file fields << current.line.to_s if current.line msg += " at #{fields.join(":")}" end msg += "; cannot redefine" Puppet.log_exception(ArgumentError.new(), msg) raise Puppet::ParseError.new(msg, param.line, param.file) end # If we've gotten this far, we're allowed to override. # Merge with previous value, if the parameter was generated with the +> # syntax. It's important that we use a copy of the new param instance # here, not the old one, and not the original new one, so that the source # is registered correctly for later overrides but the values aren't # implcitly shared when multiple resources are overrriden at once (see # ticket #3556). if param.add param = param.dup param.value = [current.value, param.value].flatten end set_parameter(param) end # Make sure the resource's parameters are all valid for the type. def validate @parameters.each do |name, param| validate_parameter(name) end rescue => detail fail Puppet::ParseError, detail.to_s end private def extract_parameters(params) params.each do |param| # Don't set the same parameter twice self.fail Puppet::ParseError, "Duplicate parameter '#{param.name}' for on #{self}" if @parameters[param.name] set_parameter(param) end end end diff --git a/lib/puppet/parser/yaml_trimmer.rb b/lib/puppet/parser/yaml_trimmer.rb index cf7870916..b9e6a260f 100644 --- a/lib/puppet/parser/yaml_trimmer.rb +++ b/lib/puppet/parser/yaml_trimmer.rb @@ -1,9 +1,9 @@ module Puppet::Parser::YamlTrimmer - REMOVE = %w{@scope @source} + REMOVE = [:@scope, :@source] def to_yaml_properties r = instance_variables - REMOVE r -= skip_for_yaml if respond_to?(:skip_for_yaml) r end end diff --git a/lib/puppet/provider/confine.rb b/lib/puppet/provider/confine.rb index 6825def7e..b28d07df3 100644 --- a/lib/puppet/provider/confine.rb +++ b/lib/puppet/provider/confine.rb @@ -1,80 +1,80 @@ # The class that handles testing whether our providers # actually work or not. require 'puppet/util' class Puppet::Provider::Confine include Puppet::Util @tests = {} class << self attr_accessor :name end def self.inherited(klass) name = klass.to_s.split("::").pop.downcase.to_sym raise "Test #{name} is already defined" if @tests.include?(name) klass.name = name @tests[name] = klass end def self.test(name) unless @tests[name] begin require "puppet/provider/confine/#{name}" rescue LoadError => detail - unless detail.to_s =~ /No such file/i + unless detail.to_s =~ /No such file|cannot load such file/i warn "Could not load confine test '#{name}': #{detail}" end # Could not find file end end @tests[name] end attr_reader :values # Mark that this confine is used for testing binary existence. attr_accessor :for_binary def for_binary? for_binary end # Used for logging. attr_accessor :label def initialize(values) values = [values] unless values.is_a?(Array) @values = values end # Provide a hook for the message when there's a failure. def message(value) "" end # Collect the results of all of them. def result values.collect { |value| pass?(value) } end # Test whether our confine matches. def valid? values.each do |value| unless pass?(value) Puppet.debug(label + ": " + message(value)) return false end end return true ensure reset end # Provide a hook for subclasses. def reset end end diff --git a/lib/puppet/provider/nameservice.rb b/lib/puppet/provider/nameservice.rb index d57052bd9..693a422e9 100644 --- a/lib/puppet/provider/nameservice.rb +++ b/lib/puppet/provider/nameservice.rb @@ -1,276 +1,276 @@ require 'puppet' # This is the parent class of all NSS classes. They're very different in # their backend, but they're pretty similar on the front-end. This class # provides a way for them all to be as similar as possible. class Puppet::Provider::NameService < Puppet::Provider class << self def autogen_default(param) defined?(@autogen_defaults) ? @autogen_defaults[symbolize(param)] : nil end def autogen_defaults(hash) @autogen_defaults ||= {} hash.each do |param, value| @autogen_defaults[symbolize(param)] = value end end def initvars @checks = {} super end def instances objects = [] listbyname do |name| objects << new(:name => name, :ensure => :present) end objects end def option(name, option) name = name.intern if name.is_a? String (defined?(@options) and @options.include? name and @options[name].include? option) ? @options[name][option] : nil end def options(name, hash) raise Puppet::DevError, "#{name} is not a valid attribute for #{resource_type.name}" unless resource_type.valid_parameter?(name) @options ||= {} @options[name] ||= {} # Set options individually, so we can call the options method # multiple times. hash.each do |param, value| @options[name][param] = value end end # List everything out by name. Abstracted a bit so that it works # for both users and groups. def listbyname names = [] Etc.send("set#{section()}ent") begin while ent = Etc.send("get#{section()}ent") names << ent.name yield ent.name if block_given? end ensure Etc.send("end#{section()}ent") end names end def resource_type=(resource_type) super @resource_type.validproperties.each do |prop| next if prop == :ensure define_method(prop) { get(prop) || :absent} unless public_method_defined?(prop) define_method(prop.to_s + "=") { |*vals| set(prop, *vals) } unless public_method_defined?(prop.to_s + "=") end end # This is annoying, but there really aren't that many options, # and this *is* built into Ruby. def section unless defined?(@resource_type) raise Puppet::DevError, "Cannot determine Etc section without a resource type" end if @resource_type.name == :group "gr" else "pw" end end def validate(name, value) name = name.intern if name.is_a? String if @checks.include? name block = @checks[name][:block] raise ArgumentError, "Invalid value #{value}: #{@checks[name][:error]}" unless block.call(value) end end def verify(name, error, &block) name = name.intern if name.is_a? String @checks[name] = {:error => error, :block => block} end private def op(property) @ops[property.name] || ("-#{property.name}") end end # Autogenerate a value. Mostly used for uid/gid, but also used heavily # with DirectoryServices, because DirectoryServices is stupid. def autogen(field) field = symbolize(field) id_generators = {:user => :uid, :group => :gid} if id_generators[@resource.class.name] == field - return autogen_id(field) + return self.class.autogen_id(field, @resource.class.name) else if value = self.class.autogen_default(field) return value elsif respond_to?("autogen_#{field}") return send("autogen_#{field}") else return nil end end end - # Autogenerate either a uid or a gid. This is hard-coded: we can only - # generate one field type per class. - def autogen_id(field) - highest = 0 - - group = method = nil - case @resource.class.name - when :user; group = :passwd; method = :uid - when :group; group = :group; method = :gid + # Autogenerate either a uid or a gid. This is not very flexible: we can + # only generate one field type per class, and get kind of confused if asked + # for both. + def self.autogen_id(field, resource_type) + # Figure out what sort of value we want to generate. + case resource_type + when :user; database = :passwd; method = :uid + when :group; database = :group; method = :gid else raise Puppet::DevError, "Invalid resource name #{resource}" end - # Make sure we don't use the same value multiple times - if defined?(@@prevauto) - @@prevauto += 1 - else - Etc.send(group) { |obj| - if obj.gid > highest - highest = obj.send(method) unless obj.send(method) > 65000 - end - } - - @@prevauto = highest + 1 + # Initialize from the data set, if needed. + unless @prevauto + # Sadly, Etc doesn't return an enumerator, it just invokes the block + # given, or returns the first record from the database. There is no + # other, more convenient enumerator for these, so we fake one with this + # loop. Thanks, Ruby, for your awesome abstractions. --daniel 2012-03-23 + highest = [] + Etc.send(database) {|entry| highest << entry.send(method) } + highest = highest.reject {|x| x > 65000 }.max + + @prevauto = highest || 1000 end - @@prevauto + # ...and finally increment and return the next value. + @prevauto += 1 end def create if exists? info "already exists" # The object already exists return nil end begin execute(self.addcmd) if feature?(:manages_password_age) && (cmd = passcmd) execute(cmd) end rescue Puppet::ExecutionFailure => detail raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}" end end def delete unless exists? info "already absent" # the object already doesn't exist return nil end begin execute(self.deletecmd) rescue Puppet::ExecutionFailure => detail raise Puppet::Error, "Could not delete #{@resource.class.name} #{@resource.name}: #{detail}" end end def ensure if exists? :present else :absent end end # Does our object exist? def exists? !!getinfo(true) end # Retrieve a specific value by name. def get(param) (hash = getinfo(false)) ? hash[param] : nil end # Retrieve what we can about our object def getinfo(refresh) if @objectinfo.nil? or refresh == true @etcmethod ||= ("get" + self.class.section.to_s + "nam").intern begin @objectinfo = Etc.send(@etcmethod, @resource[:name]) rescue ArgumentError => detail @objectinfo = nil end end # Now convert our Etc struct into a hash. @objectinfo ? info2hash(@objectinfo) : nil end # The list of all groups the user is a member of. Different # user mgmt systems will need to override this method. def groups groups = [] # Reset our group list Etc.setgrent user = @resource[:name] # Now iterate across all of the groups, adding each one our # user is a member of while group = Etc.getgrent members = group.mem groups << group.name if members.include? user end # We have to close the file, so each listing is a separate # reading of the file. Etc.endgrent groups.join(",") end # Convert the Etc struct into a hash. def info2hash(info) hash = {} self.class.resource_type.validproperties.each do |param| method = posixmethod(param) hash[param] = info.send(posixmethod(param)) if info.respond_to? method end hash end def initialize(resource) super @objectinfo = nil end def set(param, value) self.class.validate(param, value) cmd = modifycmd(param, value) raise Puppet::DevError, "Nameservice command must be an array" unless cmd.is_a?(Array) begin execute(cmd) rescue Puppet::ExecutionFailure => detail raise Puppet::Error, "Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}" end end end diff --git a/lib/puppet/provider/nameservice/directoryservice.rb b/lib/puppet/provider/nameservice/directoryservice.rb index 2bdff3bcd..083c9a60e 100644 --- a/lib/puppet/provider/nameservice/directoryservice.rb +++ b/lib/puppet/provider/nameservice/directoryservice.rb @@ -1,593 +1,592 @@ require 'puppet' require 'puppet/provider/nameservice' require 'facter/util/plist' require 'fileutils' class Puppet::Provider::NameService class DirectoryService < Puppet::Provider::NameService # JJM: Dive into the singleton_class class << self # JJM: This allows us to pass information when calling # Puppet::Type.type # e.g. Puppet::Type.type(:user).provide :directoryservice, :ds_path => "Users" # This is referenced in the get_ds_path class method attr_writer :ds_path attr_writer :macosx_version_major end initvars commands :dscl => "/usr/bin/dscl" commands :dseditgroup => "/usr/sbin/dseditgroup" commands :sw_vers => "/usr/bin/sw_vers" commands :plutil => '/usr/bin/plutil' confine :operatingsystem => :darwin defaultfor :operatingsystem => :darwin # JJM 2007-07-25: This map is used to map NameService attributes to their # corresponding DirectoryService attribute names. # See: http://images.apple.com/server/docs.Open_Directory_v10.4.pdf # JJM: Note, this is de-coupled from the Puppet::Type, and must # be actively maintained. There may also be collisions with different # types (Users, Groups, Mounts, Hosts, etc...) - @@ds_to_ns_attribute_map = { - 'RecordName' => :name, - 'PrimaryGroupID' => :gid, - 'NFSHomeDirectory' => :home, - 'UserShell' => :shell, - 'UniqueID' => :uid, - 'RealName' => :comment, - 'Password' => :password, - 'GeneratedUID' => :guid, - 'IPAddress' => :ip_address, - 'ENetAddress' => :en_address, - 'GroupMembership' => :members, - } + def ds_to_ns_attribute_map; self.class.ds_to_ns_attribute_map; end + def self.ds_to_ns_attribute_map + { + 'RecordName' => :name, + 'PrimaryGroupID' => :gid, + 'NFSHomeDirectory' => :home, + 'UserShell' => :shell, + 'UniqueID' => :uid, + 'RealName' => :comment, + 'Password' => :password, + 'GeneratedUID' => :guid, + 'IPAddress' => :ip_address, + 'ENetAddress' => :en_address, + 'GroupMembership' => :members, + } + end + # JJM The same table as above, inverted. - @@ns_to_ds_attribute_map = { - :name => 'RecordName', - :gid => 'PrimaryGroupID', - :home => 'NFSHomeDirectory', - :shell => 'UserShell', - :uid => 'UniqueID', - :comment => 'RealName', - :password => 'Password', - :guid => 'GeneratedUID', - :en_address => 'ENetAddress', - :ip_address => 'IPAddress', - :members => 'GroupMembership', - } - - @@password_hash_dir = "/var/db/shadow/hash" - @@users_plist_dir = '/var/db/dslocal/nodes/Default/users' + def ns_to_ds_attribute_map; self.class.ns_to_ds_attribute_map end + def self.ns_to_ds_attribute_map + @ns_to_ds_attribute_map ||= ds_to_ns_attribute_map.invert + end + def self.password_hash_dir + '/var/db/shadow/hash' + end + + def self.users_plist_dir + '/var/db/dslocal/nodes/Default/users' + end def self.instances # JJM Class method that provides an array of instance objects of this # type. # JJM: Properties are dependent on the Puppet::Type we're managine. type_property_array = [:name] + @resource_type.validproperties # Create a new instance of this Puppet::Type for each object present # on the system. list_all_present.collect do |name_string| self.new(single_report(name_string, *type_property_array)) end end def self.get_ds_path # JJM: 2007-07-24 This method dynamically returns the DS path we're concerned with. # For example, if we're working with an user type, this will be /Users # with a group type, this will be /Groups. # @ds_path is an attribute of the class itself. return @ds_path if defined?(@ds_path) # JJM: "Users" or "Groups" etc ... (Based on the Puppet::Type) # Remember this is a class method, so self.class is Class # Also, @resource_type seems to be the reference to the # Puppet::Type this class object is providing for. @resource_type.name.to_s.capitalize + "s" end def self.get_macosx_version_major return @macosx_version_major if defined?(@macosx_version_major) begin # Make sure we've loaded all of the facts Facter.loadfacts if Facter.value(:macosx_productversion_major) product_version_major = Facter.value(:macosx_productversion_major) else # TODO: remove this code chunk once we require Facter 1.5.5 or higher. Puppet.warning("DEPRECATION WARNING: Future versions of the directoryservice provider will require Facter 1.5.5 or newer.") product_version = Facter.value(:macosx_productversion) fail("Could not determine OS X version from Facter") if product_version.nil? product_version_major = product_version.scan(/(\d+)\.(\d+)./).join(".") end fail("#{product_version_major} is not supported by the directoryservice provider") if %w{10.0 10.1 10.2 10.3 10.4}.include?(product_version_major) @macosx_version_major = product_version_major return @macosx_version_major rescue Puppet::ExecutionFailure => detail fail("Could not determine OS X version: #{detail}") end end def self.list_all_present # JJM: List all objects of this Puppet::Type already present on the system. begin dscl_output = execute(get_exec_preamble("-list")) rescue Puppet::ExecutionFailure => detail fail("Could not get #{@resource_type.name} list from DirectoryService") end dscl_output.split("\n") end def self.parse_dscl_plist_data(dscl_output) Plist.parse_xml(dscl_output) end def self.generate_attribute_hash(input_hash, *type_properties) attribute_hash = {} input_hash.keys.each do |key| ds_attribute = key.sub("dsAttrTypeStandard:", "") - next unless (@@ds_to_ns_attribute_map.keys.include?(ds_attribute) and type_properties.include? @@ds_to_ns_attribute_map[ds_attribute]) + next unless (ds_to_ns_attribute_map.keys.include?(ds_attribute) and type_properties.include? ds_to_ns_attribute_map[ds_attribute]) ds_value = input_hash[key] - case @@ds_to_ns_attribute_map[ds_attribute] + case ds_to_ns_attribute_map[ds_attribute] when :members ds_value = ds_value # only members uses arrays so far when :gid, :uid # OS X stores objects like uid/gid as strings. # Try casting to an integer for these cases to be # consistent with the other providers and the group type # validation begin ds_value = Integer(ds_value[0]) rescue ArgumentError ds_value = ds_value[0] end else ds_value = ds_value[0] end - attribute_hash[@@ds_to_ns_attribute_map[ds_attribute]] = ds_value + attribute_hash[ds_to_ns_attribute_map[ds_attribute]] = ds_value end # NBK: need to read the existing password here as it's not actually # stored in the user record. It is stored at a path that involves the # UUID of the user record for non-Mobile local acccounts. # Mobile Accounts are out of scope for this provider for now attribute_hash[:password] = self.get_password(attribute_hash[:guid], attribute_hash[:name]) if @resource_type.validproperties.include?(:password) and Puppet.features.root? attribute_hash end def self.single_report(resource_name, *type_properties) # JJM 2007-07-24: # Given a the name of an object and a list of properties of that # object, return all property values in a hash. # # This class method returns nil if the object doesn't exist # Otherwise, it returns a hash of the object properties. all_present_str_array = list_all_present # NBK: shortcut the process if the resource is missing return nil unless all_present_str_array.include? resource_name dscl_vector = get_exec_preamble("-read", resource_name) begin dscl_output = execute(dscl_vector) rescue Puppet::ExecutionFailure => detail fail("Could not get report. command execution failed.") end # (#11593) Remove support for OS X 10.4 and earlier fail_if_wrong_version dscl_plist = self.parse_dscl_plist_data(dscl_output) self.generate_attribute_hash(dscl_plist, *type_properties) end def self.fail_if_wrong_version fail("Puppet does not support OS X versions < 10.5") unless self.get_macosx_version_major >= "10.5" end def self.get_exec_preamble(ds_action, resource_name = nil) # JJM 2007-07-24 # DSCL commands are often repetitive and contain the same positional # arguments over and over. See http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/additionalfeatures/chapter_10_section_9.html # for an example of what I mean. # This method spits out proper DSCL commands for us. # We EXPECT name to be @resource[:name] when called from an instance object. # (#11593) Remove support for OS X 10.4 and earlier fail_if_wrong_version command_vector = [ command(:dscl), "-plist", "." ] # JJM: The actual action to perform. See "man dscl" # Common actiosn: -create, -delete, -merge, -append, -passwd command_vector << ds_action # JJM: get_ds_path will spit back "Users" or "Groups", # etc... Depending on the Puppet::Type of our self. if resource_name command_vector << "/#{get_ds_path}/#{resource_name}" else command_vector << "/#{get_ds_path}" end # JJM: This returns most of the preamble of the command. # e.g. 'dscl / -create /Users/mccune' command_vector end def self.set_password(resource_name, guid, password_hash) # Use Puppet::Util::Package.versioncmp() to catch the scenario where a # version '10.10' would be < '10.7' with simple string comparison. This # if-statement only executes if the current version is less-than 10.7 if (Puppet::Util::Package.versioncmp(get_macosx_version_major, '10.7') == -1) - password_hash_file = "#{@@password_hash_dir}/#{guid}" + password_hash_file = "#{password_hash_dir}/#{guid}" begin File.open(password_hash_file, 'w') { |f| f.write(password_hash)} rescue Errno::EACCES => detail fail("Could not write to password hash file: #{detail}") end # NBK: For shadow hashes, the user AuthenticationAuthority must contain a value of # ";ShadowHash;". The LKDC in 10.5 makes this more interesting though as it # will dynamically generate ;Kerberosv5;;username@LKDC:SHA1 attributes if # missing. Thus we make sure we only set ;ShadowHash; if it is missing, and # we can do this with the merge command. This allows people to continue to # use other custom AuthenticationAuthority attributes without stomping on them. # # There is a potential problem here in that we're only doing this when setting # the password, and the attribute could get modified at other times while the # hash doesn't change and so this doesn't get called at all... but # without switching all the other attributes to merge instead of create I can't # see a simple enough solution for this that doesn't modify the user record # every single time. This should be a rather rare edge case. (famous last words) dscl_vector = self.get_exec_preamble("-merge", resource_name) dscl_vector << "AuthenticationAuthority" << ";ShadowHash;" begin dscl_output = execute(dscl_vector) rescue Puppet::ExecutionFailure => detail fail("Could not set AuthenticationAuthority.") end else # 10.7 uses salted SHA512 password hashes which are 128 characters plus # an 8 character salt. Previous versions used a SHA1 hash padded with # zeroes. If someone attempts to use a password hash that worked with # a previous version of OX X, we will fail early and warn them. if password_hash.length != 136 fail("OS X 10.7 requires a Salted SHA512 hash password of 136 characters. \ Please check your password and try again.") end - if File.exists?("#{@@users_plist_dir}/#{resource_name}.plist") + if File.exists?("#{users_plist_dir}/#{resource_name}.plist") # If a plist already exists in /var/db/dslocal/nodes/Default/users, then # we will need to extract the binary plist from the 'ShadowHashData' # key, log the new password into the resultant plist's 'SALTED-SHA512' # key, and then save the entire structure back. users_plist = Plist::parse_xml(plutil( '-convert', 'xml1', '-o', '/dev/stdout', \ - "#{@@users_plist_dir}/#{resource_name}.plist")) + "#{users_plist_dir}/#{resource_name}.plist")) # users_plist['ShadowHashData'][0].string is actually a binary plist # that's nested INSIDE the user's plist (which itself is a binary # plist). password_hash_plist = users_plist['ShadowHashData'][0].string converted_hash_plist = convert_binary_to_xml(password_hash_plist) # converted_hash_plist['SALTED-SHA512'].string expects a Base64 encoded # string. The password_hash provided as a resource attribute is a # hex value. We need to convert the provided hex value to a Base64 # encoded string to nest it in the converted hash plist. converted_hash_plist['SALTED-SHA512'].string = \ password_hash.unpack('a2'*(password_hash.size/2)).collect { |i| i.hex.chr }.join # Finally, we can convert the nested plist back to binary, embed it # into the user's plist, and convert the resultant plist back to # a binary plist. changed_plist = convert_xml_to_binary(converted_hash_plist) users_plist['ShadowHashData'][0].string = changed_plist - Plist::Emit.save_plist(users_plist, "#{@@users_plist_dir}/#{resource_name}.plist") - plutil('-convert', 'binary1', "#{@@users_plist_dir}/#{resource_name}.plist") + Plist::Emit.save_plist(users_plist, "#{users_plist_dir}/#{resource_name}.plist") + plutil('-convert', 'binary1', "#{users_plist_dir}/#{resource_name}.plist") end end end def self.get_password(guid, username) # Use Puppet::Util::Package.versioncmp() to catch the scenario where a # version '10.10' would be < '10.7' with simple string comparison. This # if-statement only executes if the current version is less-than 10.7 if (Puppet::Util::Package.versioncmp(get_macosx_version_major, '10.7') == -1) password_hash = nil - password_hash_file = "#{@@password_hash_dir}/#{guid}" + password_hash_file = "#{password_hash_dir}/#{guid}" if File.exists?(password_hash_file) and File.file?(password_hash_file) fail("Could not read password hash file at #{password_hash_file}") if not File.readable?(password_hash_file) f = File.new(password_hash_file) password_hash = f.read f.close end password_hash else - if File.exists?("#{@@users_plist_dir}/#{username}.plist") + if File.exists?("#{users_plist_dir}/#{username}.plist") # If a plist exists in /var/db/dslocal/nodes/Default/users, we will # extract the binary plist from the 'ShadowHashData' key, decode the # salted-SHA512 password hash, and then return it. - users_plist = Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', "#{@@users_plist_dir}/#{username}.plist")) + users_plist = Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', "#{users_plist_dir}/#{username}.plist")) if users_plist['ShadowHashData'] # users_plist['ShadowHashData'][0].string is actually a binary plist # that's nested INSIDE the user's plist (which itself is a binary # plist). password_hash_plist = users_plist['ShadowHashData'][0].string converted_hash_plist = convert_binary_to_xml(password_hash_plist) # converted_hash_plist['SALTED-SHA512'].string is a Base64 encoded # string. The password_hash provided as a resource attribute is a # hex value. We need to convert the Base64 encoded string to a # hex value and provide it back to Puppet. password_hash = converted_hash_plist['SALTED-SHA512'].string.unpack("H*")[0] password_hash end end end end # This method will accept a hash that has been returned from Plist::parse_xml # and convert it to a binary plist (string value). def self.convert_xml_to_binary(plist_data) Puppet.debug('Converting XML plist to binary') Puppet.debug('Executing: \'plutil -convert binary1 -o - -\'') IO.popen('plutil -convert binary1 -o - -', mode='r+') do |io| io.write plist_data.to_plist io.close_write @converted_plist = io.read end @converted_plist end # This method will accept a binary plist (as a string) and convert it to a # hash via Plist::parse_xml. def self.convert_binary_to_xml(plist_data) Puppet.debug('Converting binary plist to XML') Puppet.debug('Executing: \'plutil -convert xml1 -o - -\'') IO.popen('plutil -convert xml1 -o - -', mode='r+') do |io| io.write plist_data io.close_write @converted_plist = io.read end Puppet.debug('Converting XML values to a hash.') @plist_hash = Plist::parse_xml(@converted_plist) @plist_hash end # Unlike most other *nixes, OS X doesn't provide built in functionality # for automatically assigning uids and gids to accounts, so we set up these # methods for consumption by functionality like --mkusers # By default we restrict to a reasonably sane range for system accounts def self.next_system_id(id_type, min_id=20) dscl_args = ['.', '-list'] if id_type == 'uid' dscl_args << '/Users' << 'uid' elsif id_type == 'gid' dscl_args << '/Groups' << 'gid' else fail("Invalid id_type #{id_type}. Only 'uid' and 'gid' supported") end dscl_out = dscl(dscl_args) # We're ok with throwing away negative uids here. ids = dscl_out.split.compact.collect { |l| l.to_i if l.match(/^\d+$/) } ids.compact!.sort! { |a,b| a.to_f <=> b.to_f } # We're just looking for an unused id in our sorted array. ids.each_index do |i| next_id = ids[i] + 1 return next_id if ids[i+1] != next_id and next_id >= min_id end end def ensure=(ensure_value) super # We need to loop over all valid properties for the type we're # managing and call the method which sets that property value # dscl can't create everything at once unfortunately. if ensure_value == :present @resource.class.validproperties.each do |name| next if name == :ensure # LAK: We use property.sync here rather than directly calling # the settor method because the properties might do some kind # of conversion. In particular, the user gid property might # have a string and need to convert it to a number if @resource.should(name) @resource.property(name).sync elsif value = autogen(name) self.send(name.to_s + "=", value) else next end end end end def password=(passphrase) exec_arg_vector = self.class.get_exec_preamble("-read", @resource.name) - exec_arg_vector << @@ns_to_ds_attribute_map[:guid] + exec_arg_vector << ns_to_ds_attribute_map[:guid] begin guid_output = execute(exec_arg_vector) guid_plist = Plist.parse_xml(guid_output) # Although GeneratedUID like all DirectoryService values can be multi-valued # according to the schema, in practice user accounts cannot have multiple UUIDs # otherwise Bad Things Happen, so we just deal with the first value. - guid = guid_plist["dsAttrTypeStandard:#{@@ns_to_ds_attribute_map[:guid]}"][0] + guid = guid_plist["dsAttrTypeStandard:#{ns_to_ds_attribute_map[:guid]}"][0] self.class.set_password(@resource.name, guid, passphrase) rescue Puppet::ExecutionFailure => detail fail("Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}") end end # NBK: we override @parent.set as we need to execute a series of commands # to deal with array values, rather than the single command nameservice.rb # expects to be returned by modifycmd. Thus we don't bother defining modifycmd. def set(param, value) self.class.validate(param, value) current_members = @property_value_cache_hash[:members] if param == :members # If we are meant to be authoritative for the group membership # then remove all existing members who haven't been specified # in the manifest. remove_unwanted_members(current_members, value) if @resource[:auth_membership] and not current_members.nil? # if they're not a member, make them one. add_members(current_members, value) else exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name]) # JJM: The following line just maps the NS name to the DS name # e.g. { :uid => 'UniqueID' } - exec_arg_vector << @@ns_to_ds_attribute_map[symbolize(param)] + exec_arg_vector << ns_to_ds_attribute_map[symbolize(param)] # JJM: The following line sends the actual value to set the property to exec_arg_vector << value.to_s begin execute(exec_arg_vector) rescue Puppet::ExecutionFailure => detail fail("Could not set #{param} on #{@resource.class.name}[#{@resource.name}]: #{detail}") end end end # NBK: we override @parent.create as we need to execute a series of commands # to create objects with dscl, rather than the single command nameservice.rb # expects to be returned by addcmd. Thus we don't bother defining addcmd. def create if exists? info "already exists" return nil end # NBK: First we create the object with a known guid so we can set the contents # of the password hash if required # Shelling out sucks, but for a single use case it doesn't seem worth # requiring people install a UUID library that doesn't come with the system. # This should be revisited if Puppet starts managing UUIDs for other platform # user records. guid = %x{/usr/bin/uuidgen}.chomp exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name]) - exec_arg_vector << @@ns_to_ds_attribute_map[:guid] << guid + exec_arg_vector << ns_to_ds_attribute_map[:guid] << guid begin execute(exec_arg_vector) rescue Puppet::ExecutionFailure => detail fail("Could not set GeneratedUID for #{@resource.class.name} #{@resource.name}: #{detail}") end if value = @resource.should(:password) and value != "" self.class.set_password(@resource[:name], guid, value) end # Now we create all the standard properties Puppet::Type.type(@resource.class.name).validproperties.each do |property| next if property == :ensure value = @resource.should(property) if property == :gid and value.nil? value = self.class.next_system_id(id_type='gid') end if property == :uid and value.nil? value = self.class.next_system_id(id_type='uid') end if value != "" and not value.nil? if property == :members add_members(nil, value) else exec_arg_vector = self.class.get_exec_preamble("-create", @resource[:name]) - exec_arg_vector << @@ns_to_ds_attribute_map[symbolize(property)] + exec_arg_vector << ns_to_ds_attribute_map[symbolize(property)] next if property == :password # skip setting the password here exec_arg_vector << value.to_s begin execute(exec_arg_vector) rescue Puppet::ExecutionFailure => detail fail("Could not create #{@resource.class.name} #{@resource.name}: #{detail}") end end end end end def remove_unwanted_members(current_members, new_members) current_members.each do |member| if not new_members.flatten.include?(member) cmd = [:dseditgroup, "-o", "edit", "-n", ".", "-d", member, @resource[:name]] begin execute(cmd) rescue Puppet::ExecutionFailure => detail # TODO: We're falling back to removing the member using dscl due to rdar://8481241 # This bug causes dseditgroup to fail to remove a member if that member doesn't exist cmd = [:dscl, ".", "-delete", "/Groups/#{@resource.name}", "GroupMembership", member] begin execute(cmd) rescue Puppet::ExecutionFailure => detail fail("Could not remove #{member} from group: #{@resource.name}, #{detail}") end end end end end def add_members(current_members, new_members) new_members.flatten.each do |new_member| if current_members.nil? or not current_members.include?(new_member) cmd = [:dseditgroup, "-o", "edit", "-n", ".", "-a", new_member, @resource[:name]] begin execute(cmd) rescue Puppet::ExecutionFailure => detail fail("Could not add #{new_member} to group: #{@resource.name}, #{detail}") end end end end def deletecmd # JJM: Like addcmd, only called when deleting the object itself # Note, this isn't used to delete properties of the object, # at least that's how I understand it... self.class.get_exec_preamble("-delete", @resource[:name]) end def getinfo(refresh = false) # JJM 2007-07-24: # Override the getinfo method, which is also defined in nameservice.rb # This method returns and sets @infohash # I'm not re-factoring the name "getinfo" because this method will be # most likely called by nameservice.rb, which I didn't write. if refresh or (! defined?(@property_value_cache_hash) or ! @property_value_cache_hash) # JJM 2007-07-24: OK, there's a bit of magic that's about to # happen... Let's see how strong my grip has become... =) # # self is a provider instance of some Puppet::Type, like # Puppet::Type::User::ProviderDirectoryservice for the case of the # user type and this provider. # # self.class looks like "user provider directoryservice", if that # helps you ... # # self.class.resource_type is a reference to the Puppet::Type class, # probably Puppet::Type::User or Puppet::Type::Group, etc... # # self.class.resource_type.validproperties is a class method, # returning an Array of the valid properties of that specific # Puppet::Type. # # So... something like [:comment, :home, :password, :shell, :uid, # :groups, :ensure, :gid] # # Ultimately, we add :name to the list, delete :ensure from the # list, then report on the remaining list. Pretty whacky, ehh? type_properties = [:name] + self.class.resource_type.validproperties type_properties.delete(:ensure) if type_properties.include? :ensure type_properties << :guid # append GeneratedUID so we just get the report here @property_value_cache_hash = self.class.single_report(@resource[:name], *type_properties) [:uid, :gid].each do |param| @property_value_cache_hash[param] = @property_value_cache_hash[param].to_i if @property_value_cache_hash and @property_value_cache_hash.include?(param) end end @property_value_cache_hash end end end diff --git a/lib/puppet/provider/package/apt.rb b/lib/puppet/provider/package/apt.rb index 74b261a49..b7bc031b8 100755 --- a/lib/puppet/provider/package/apt.rb +++ b/lib/puppet/provider/package/apt.rb @@ -1,111 +1,108 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do # Provide sorting functionality include Puppet::Util::Package desc "Package management via `apt-get`." has_feature :versionable commands :aptget => "/usr/bin/apt-get" commands :aptcache => "/usr/bin/apt-cache" commands :preseed => "/usr/bin/debconf-set-selections" defaultfor :operatingsystem => [:debian, :ubuntu] ENV['DEBIAN_FRONTEND'] = "noninteractive" # disable common apt helpers to allow non-interactive package installs ENV['APT_LISTBUGS_FRONTEND'] = "none" ENV['APT_LISTCHANGES_FRONTEND'] = "none" # A derivative of DPKG; this is how most people actually manage # Debian boxes, and the only thing that differs is that it can # install packages from remote sites. def checkforcdrom - unless defined?(@@checkedforcdrom) - if FileTest.exists? "/etc/apt/sources.list" - @@checkedforcdrom = !!(File.read("/etc/apt/sources.list") =~ /^[^#]*cdrom:/) - else - # This is basically a pathalogical case, but we'll just - # ignore it - @@checkedforcdrom = false - end - end - - if @@checkedforcdrom and @resource[:allowcdrom] != :true + have_cdrom = begin + !!(File.read("/etc/apt/sources.list") =~ /^[^#]*cdrom:/) + rescue + # This is basically pathological... + false + end + + if have_cdrom and @resource[:allowcdrom] != :true raise Puppet::Error, "/etc/apt/sources.list contains a cdrom source; not installing. Use 'allowcdrom' to override this failure." end end # Install a package using 'apt-get'. This function needs to support # installing a specific version. def install self.run_preseed if @resource[:responsefile] should = @resource[:ensure] checkforcdrom cmd = %w{-q -y} keep = "" if config = @resource[:configfiles] if config == :keep cmd << "-o" << 'DPkg::Options::=--force-confold' else cmd << "-o" << 'DPkg::Options::=--force-confnew' end end str = @resource[:name] case should when true, false, Symbol # pass else # Add the package version and --force-yes option str += "=#{should}" cmd << "--force-yes" end cmd << :install << str aptget(*cmd) end # What's the latest package version available? def latest output = aptcache :policy, @resource[:name] if output =~ /Candidate:\s+(\S+)\s/ return $1 else self.err "Could not find latest version" return nil end end # # preseeds answers to dpkg-set-selection from the "responsefile" # def run_preseed if response = @resource[:responsefile] and FileTest.exist?(response) self.info("Preseeding #{response} to debconf-set-selections") preseed response else self.info "No responsefile specified or non existant, not preseeding anything" end end def uninstall self.run_preseed if @resource[:responsefile] aptget "-y", "-q", :remove, @resource[:name] end def purge self.run_preseed if @resource[:responsefile] aptget '-y', '-q', :remove, '--purge', @resource[:name] # workaround a "bug" in apt, that already removed packages are not purged super end end diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb index 2cd907b7f..98b5ce67f 100755 --- a/lib/puppet/provider/package/gem.rb +++ b/lib/puppet/provider/package/gem.rb @@ -1,121 +1,123 @@ require 'puppet/provider/package' require 'uri' # Ruby gems support. Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package do desc "Ruby Gem support. If a URL is passed via `source`, then that URL is used as the remote gem repository; if a source is present but is not a valid URL, it will be interpreted as the path to a local gem file. If source is not present at all, the gem will be installed from the default gem repositories." has_feature :versionable commands :gemcmd => "gem" def self.gemlist(options) gem_list_command = [command(:gemcmd), "list"] if options[:local] gem_list_command << "--local" else gem_list_command << "--remote" end if name = options[:justme] gem_list_command << name + "$" end begin - list = execute(gem_list_command).lines.map {|set| gemsplit(set) } + list = execute(gem_list_command).lines. + map {|set| gemsplit(set) }. + reject {|item| item.nil? } rescue Puppet::ExecutionFailure => detail raise Puppet::Error, "Could not list gems: #{detail}" end if options[:justme] return list.shift else return list end end def self.gemsplit(desc) # `gem list` when output console has a line like: # *** LOCAL GEMS *** # but when it's not to the console that line # and all blank lines are stripped # so we don't need to check for them if desc =~ /^(\S+)\s+\((.+)\)/ name = $1 versions = $2.split(/,\s*/) { :name => name, :ensure => versions, :provider => :gem } else - Puppet.warning "Could not match #{desc}" + Puppet.warning "Could not match #{desc}" unless desc.chomp.empty? nil end end def self.instances(justme = false) gemlist(:local => true).collect do |hash| new(hash) end end def install(useversion = true) command = [command(:gemcmd), "install"] command << "-v" << resource[:ensure] if (! resource[:ensure].is_a? Symbol) and useversion # Always include dependencies command << "--include-dependencies" if source = resource[:source] begin uri = URI.parse(source) rescue => detail fail "Invalid source '#{uri}': #{detail}" end case uri.scheme when nil # no URI scheme => interpret the source as a local file command << source when /file/i command << uri.path when 'puppet' # we don't support puppet:// URLs (yet) raise Puppet::Error.new("puppet:// URLs are not supported as gem sources") else # interpret it as a gem repository command << "--source" << "#{source}" << resource[:name] end else command << "--no-rdoc" << "--no-ri" << resource[:name] end output = execute(command) # Apparently some stupid gem versions don't exit non-0 on failure self.fail "Could not install: #{output.chomp}" if output.include?("ERROR") end def latest # This always gets the latest version available. hash = self.class.gemlist(:justme => resource[:name]) hash[:ensure] end def query self.class.gemlist(:justme => resource[:name], :local => true) end def uninstall gemcmd "uninstall", "-x", "-a", resource[:name] end def update self.install(false) end end diff --git a/lib/puppet/provider/service/bsd.rb b/lib/puppet/provider/service/bsd.rb index 0c019fdd0..5b73dfc64 100644 --- a/lib/puppet/provider/service/bsd.rb +++ b/lib/puppet/provider/service/bsd.rb @@ -1,49 +1,51 @@ # Manage FreeBSD services. Puppet::Type.type(:service).provide :bsd, :parent => :init do desc <<-EOT FreeBSD's (and probably NetBSD's?) form of `init`-style service management. Uses `rc.conf.d` for service enabling and disabling. EOT confine :operatingsystem => [:freebsd, :netbsd, :openbsd] - @@rcconf_dir = '/etc/rc.conf.d' + def rcconf_dir + '/etc/rc.conf.d' + end def self.defpath superclass.defpath end # remove service file from rc.conf.d to disable it def disable - rcfile = File.join(@@rcconf_dir, @model[:name]) + rcfile = File.join(rcconf_dir, @model[:name]) File.delete(rcfile) if File.exists?(rcfile) end # if the service file exists in rc.conf.d then it's already enabled def enabled? - rcfile = File.join(@@rcconf_dir, @model[:name]) + rcfile = File.join(rcconf_dir, @model[:name]) return :true if File.exists?(rcfile) :false end # enable service by creating a service file under rc.conf.d with the # proper contents def enable - Dir.mkdir(@@rcconf_dir) if not File.exists?(@@rcconf_dir) - rcfile = File.join(@@rcconf_dir, @model[:name]) + Dir.mkdir(rcconf_dir) if not File.exists?(rcconf_dir) + rcfile = File.join(rcconf_dir, @model[:name]) open(rcfile, 'w') { |f| f << "%s_enable=\"YES\"\n" % @model[:name] } end # Override stop/start commands to use one's and the avoid race condition # where provider trys to stop/start the service before it is enabled def startcmd [self.initscript, :onestart] end def stopcmd [self.initscript, :onestop] end end diff --git a/lib/puppet/provider/service/freebsd.rb b/lib/puppet/provider/service/freebsd.rb index 5e1a36d46..6c090908a 100644 --- a/lib/puppet/provider/service/freebsd.rb +++ b/lib/puppet/provider/service/freebsd.rb @@ -1,139 +1,139 @@ Puppet::Type.type(:service).provide :freebsd, :parent => :init do desc "Provider for FreeBSD. Uses the `rcvar` argument of init scripts and parses/edits rc files." confine :operatingsystem => [:freebsd] defaultfor :operatingsystem => [:freebsd] - @@rcconf = '/etc/rc.conf' - @@rcconf_local = '/etc/rc.conf.local' - @@rcconf_dir = '/etc/rc.conf.d' + def rcconf() '/etc/rc.conf' end + def rcconf_local() '/etc/rc.conf.local' end + def rcconf_dir() '/etc/rc.conf.d' end def self.defpath superclass.defpath end # Executing an init script with the 'rcvar' argument returns # the service name, rcvar name and whether it's enabled/disabled def rcvar rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false) rcvar = rcvar.split("\n") rcvar.delete_if {|str| str =~ /^#\s*$/} rcvar[1] = rcvar[1].gsub(/^\$/, '') rcvar end # Extract service name def service_name name = self.rcvar[0] self.error("No service name found in rcvar") if name.nil? name = name.gsub!(/# (.*)/, '\1') self.error("Service name is empty") if name.nil? self.debug("Service name is #{name}") name end # Extract rcvar name def rcvar_name name = self.rcvar[1] self.error("No rcvar name found in rcvar") if name.nil? name = name.gsub!(/(.*)_enable=(.*)/, '\1') self.error("rcvar name is empty") if name.nil? self.debug("rcvar name is #{name}") name end # Extract rcvar value def rcvar_value value = self.rcvar[1] self.error("No rcvar value found in rcvar") if value.nil? value = value.gsub!(/(.*)_enable="?(\w+)"?/, '\2') self.error("rcvar value is empty") if value.nil? self.debug("rcvar value is #{value}") value end # Edit rc files and set the service to yes/no def rc_edit(yesno) service = self.service_name rcvar = self.rcvar_name self.debug("Editing rc files: setting #{rcvar} to #{yesno} for #{service}") self.rc_add(service, rcvar, yesno) if not self.rc_replace(service, rcvar, yesno) end # Try to find an existing setting in the rc files # and replace the value def rc_replace(service, rcvar, yesno) success = false # Replace in all files, not just in the first found with a match - [@@rcconf, @@rcconf_local, @@rcconf_dir + "/#{service}"].each do |filename| + [rcconf, rcconf_local, rcconf_dir + "/#{service}"].each do |filename| if File.exists?(filename) s = File.read(filename) if s.gsub!(/(#{rcvar}_enable)=\"?(YES|NO)\"?/, "\\1=\"#{yesno}\"") File.open(filename, File::WRONLY) { |f| f << s } self.debug("Replaced in #{filename}") success = true end end end success end # Add a new setting to the rc files def rc_add(service, rcvar, yesno) append = "\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\"\n" # First, try the one-file-per-service style - if File.exists?(@@rcconf_dir) - File.open(@@rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) { + if File.exists?(rcconf_dir) + File.open(rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) { |f| f << append self.debug("Appended to #{f.path}") } else # Else, check the local rc file first, but don't create it - if File.exists?(@@rcconf_local) - File.open(@@rcconf_local, File::WRONLY | File::APPEND) { + if File.exists?(rcconf_local) + File.open(rcconf_local, File::WRONLY | File::APPEND) { |f| f << append self.debug("Appended to #{f.path}") } else # At last use the standard rc.conf file - File.open(@@rcconf, File::WRONLY | File::APPEND | File::CREAT, 0644) { + File.open(rcconf, File::WRONLY | File::APPEND | File::CREAT, 0644) { |f| f << append self.debug("Appended to #{f.path}") } end end end def enabled? if /YES$/ =~ self.rcvar_value self.debug("Is enabled") return :true end self.debug("Is disabled") :false end def enable self.debug("Enabling") self.rc_edit("YES") end def disable self.debug("Disabling") self.rc_edit("NO") end def startcmd [self.initscript, :onestart] end def stopcmd [self.initscript, :onestop] end def statuscmd [self.initscript, :onestatus] end end diff --git a/lib/puppet/resource/status.rb b/lib/puppet/resource/status.rb index dea8c105d..ed2e019a3 100644 --- a/lib/puppet/resource/status.rb +++ b/lib/puppet/resource/status.rb @@ -1,79 +1,82 @@ module Puppet class Resource class Status include Puppet::Util::Tagging include Puppet::Util::Logging attr_accessor :resource, :node, :file, :line, :current_values, :status, :evaluation_time STATES = [:skipped, :failed, :failed_to_restart, :restarted, :changed, :out_of_sync, :scheduled] attr_accessor *STATES attr_reader :source_description, :default_log_level, :time, :resource attr_reader :change_count, :out_of_sync_count, :resource_type, :title - YAML_ATTRIBUTES = %w{@resource @file @line @evaluation_time @change_count @out_of_sync_count @tags @time @events @out_of_sync @changed @resource_type @title @skipped @failed} + YAML_ATTRIBUTES = %w{@resource @file @line @evaluation_time @change_count + @out_of_sync_count @tags @time @events @out_of_sync + @changed @resource_type @title @skipped @failed}. + map(&:to_sym) # Provide a boolean method for each of the states. STATES.each do |attr| define_method("#{attr}?") do !! send(attr) end end def <<(event) add_event(event) self end def add_event(event) @events << event if event.status == 'failure' self.failed = true elsif event.status == 'success' @change_count += 1 @changed = true end if event.status != 'audit' @out_of_sync_count += 1 @out_of_sync = true end end def events @events end def initialize(resource) @source_description = resource.path @resource = resource.to_s @change_count = 0 @out_of_sync_count = 0 @changed = false @out_of_sync = false @skipped = false @failed = false [:file, :line].each do |attr| send(attr.to_s + "=", resource.send(attr)) end tag(*resource.tags) @time = Time.now @events = [] @resource_type = resource.type.to_s.capitalize @title = resource.title end def to_yaml_properties (YAML_ATTRIBUTES & instance_variables).sort end private def log_source source_description end end end end diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb index fd38bb2cc..c1a198867 100644 --- a/lib/puppet/simple_graph.rb +++ b/lib/puppet/simple_graph.rb @@ -1,550 +1,547 @@ require 'puppet/external/dot' require 'puppet/relationship' require 'set' # A hopefully-faster graph class to replace the use of GRATR. class Puppet::SimpleGraph # # All public methods of this class must maintain (assume ^ ensure) the following invariants, where "=~=" means # equiv. up to order: # # @in_to.keys =~= @out_to.keys =~= all vertices # @in_to.values.collect { |x| x.values }.flatten =~= @out_from.values.collect { |x| x.values }.flatten =~= all edges # @in_to[v1][v2] =~= @out_from[v2][v1] =~= all edges from v1 to v2 # @in_to [v].keys =~= vertices with edges leading to v # @out_from[v].keys =~= vertices with edges leading from v # no operation may shed reference loops (for gc) # recursive operation must scale with the depth of the spanning trees, or better (e.g. no recursion over the set # of all vertices, etc.) # # This class is intended to be used with DAGs. However, if the # graph has a cycle, it will not cause non-termination of any of the # algorithms. # def initialize @in_to = {} @out_from = {} @upstream_from = {} @downstream_from = {} end # Clear our graph. def clear @in_to.clear @out_from.clear @upstream_from.clear @downstream_from.clear end # Which resources depend upon the given resource. def dependencies(resource) vertex?(resource) ? upstream_from_vertex(resource).keys : [] end def dependents(resource) vertex?(resource) ? downstream_from_vertex(resource).keys : [] end # Whether our graph is directed. Always true. Used to produce dot files. def directed? true end # Determine all of the leaf nodes below a given vertex. def leaves(vertex, direction = :out) tree_from_vertex(vertex, direction).keys.find_all { |c| adjacent(c, :direction => direction).empty? } end # Collect all of the edges that the passed events match. Returns # an array of edges. def matching_edges(event, base = nil) source = base || event.resource unless vertex?(source) Puppet.warning "Got an event from invalid vertex #{source.ref}" return [] end # Get all of the edges that this vertex should forward events # to, which is the same thing as saying all edges directly below # This vertex in the graph. @out_from[source].values.flatten.find_all { |edge| edge.match?(event.name) } end # Return a reversed version of this graph. def reversal result = self.class.new vertices.each { |vertex| result.add_vertex(vertex) } edges.each do |edge| result.add_edge edge.class.new(edge.target, edge.source, edge.label) end result end # Return the size of the graph. def size vertices.size end def to_a vertices end # This is a simple implementation of Tarjan's algorithm to find strongly # connected components in the graph; this is a fairly ugly implementation, # because I can't just decorate the vertices themselves. # # This method has an unhealthy relationship with the find_cycles_in_graph # method below, which contains the knowledge of how the state object is # maintained. def tarjan(root, s) # initialize the recursion stack we use to work around the nasty lack of a # decent Ruby stack. recur = [{ :node => root }] while not recur.empty? do frame = recur.last vertex = frame[:node] case frame[:step] when nil then s[:index][vertex] = s[:number] s[:lowlink][vertex] = s[:number] s[:number] = s[:number] + 1 s[:stack].push(vertex) s[:seen][vertex] = true frame[:children] = adjacent(vertex) frame[:step] = :children when :children then if frame[:children].length > 0 then child = frame[:children].shift if ! s[:index][child] then # Never seen, need to recurse. frame[:step] = :after_recursion frame[:child] = child recur.push({ :node => child }) elsif s[:seen][child] then s[:lowlink][vertex] = [s[:lowlink][vertex], s[:index][child]].min end else if s[:lowlink][vertex] == s[:index][vertex] then this_scc = [] begin top = s[:stack].pop s[:seen][top] = false this_scc << top end until top == vertex s[:scc] << this_scc end recur.pop # done with this node, finally. end when :after_recursion then s[:lowlink][vertex] = [s[:lowlink][vertex], s[:lowlink][frame[:child]]].min frame[:step] = :children else fail "#{frame[:step]} is an unknown step" end end end # Find all cycles in the graph by detecting all the strongly connected # components, then eliminating everything with a size of one as # uninteresting - which it is, because it can't be a cycle. :) # # This has an unhealthy relationship with the 'tarjan' method above, which # it uses to implement the detection of strongly connected components. def find_cycles_in_graph state = { :number => 0, :index => {}, :lowlink => {}, :scc => [], :stack => [], :seen => {} } # we usually have a disconnected graph, must walk all possible roots vertices.each do |vertex| if ! state[:index][vertex] then tarjan vertex, state end end # To provide consistent results to the user, given that a hash is never # assured to return the same order, and given our graph processing is # based on hash tables, we need to sort the cycles internally, as well as # the set of cycles. # # Given we are in a failure state here, any extra cost is more or less # irrelevant compared to the cost of a fix - which is on a human # time-scale. state[:scc].select { |c| c.length > 1 }.map {|x| x.sort }.sort end # Perform a BFS on the sub graph representing the cycle, with a view to # generating a sufficient set of paths to report the cycle meaningfully, and # ideally usefully, for the end user. # # BFS is preferred because it will generally report the shortest paths # through the graph first, which are more likely to be interesting to the # user. I think; it would be interesting to verify that. --daniel 2011-01-23 def paths_in_cycle(cycle, max_paths = 1) raise ArgumentError, "negative or zero max_paths" if max_paths < 1 # Calculate our filtered outbound vertex lists... adj = {} cycle.each do |vertex| adj[vertex] = adjacent(vertex).select{|s| cycle.member? s} end found = [] # frame struct is vertex, [path] stack = [[cycle.first, []]] while frame = stack.shift do if frame[1].member?(frame[0]) then found << frame[1] + [frame[0]] break if found.length >= max_paths else adj[frame[0]].each do |to| stack.push [to, frame[1] + [frame[0]]] end end end return found.sort end def report_cycles_in_graph cycles = find_cycles_in_graph n = cycles.length # where is "pluralize"? --daniel 2011-01-22 return if n == 0 s = n == 1 ? '' : 's' message = "Found #{n} dependency cycle#{s}:\n" cycles.each do |cycle| paths = paths_in_cycle(cycle) message += paths.map{ |path| '(' + path.join(" => ") + ')'}.join("\n") + "\n" end if Puppet[:graph] then filename = write_cycles_to_graph(cycles) message += "Cycle graph written to #{filename}." else message += "Try the '--graph' option and opening the " message += "resulting '.dot' file in OmniGraffle or GraphViz" end raise Puppet::Error, message end def write_cycles_to_graph(cycles) # This does not use the DOT graph library, just writes the content # directly. Given the complexity of this, there didn't seem much point # using a heavy library to generate exactly the same content. --daniel 2011-01-27 Puppet.settings.use(:graphing) graph = ["digraph Resource_Cycles {"] graph << ' label = "Resource Cycles"' cycles.each do |cycle| paths_in_cycle(cycle, 10).each do |path| graph << path.map { |v| '"' + v.to_s.gsub(/"/, '\\"') + '"' }.join(" -> ") end end graph << '}' filename = File.join(Puppet[:graphdir], "cycles.dot") File.open(filename, "w") { |f| f.puts graph } return filename end # Add a new vertex to the graph. def add_vertex(vertex) @in_to[vertex] ||= {} @out_from[vertex] ||= {} end # Remove a vertex from the graph. def remove_vertex!(v) return unless vertex?(v) @upstream_from.clear @downstream_from.clear (@in_to[v].values+@out_from[v].values).flatten.each { |e| remove_edge!(e) } @in_to.delete(v) @out_from.delete(v) end # Test whether a given vertex is in the graph. def vertex?(v) @in_to.include?(v) end # Return a list of all vertices. def vertices @in_to.keys end # Add a new edge. The graph user has to create the edge instance, # since they have to specify what kind of edge it is. def add_edge(e,*a) return add_relationship(e,*a) unless a.empty? @upstream_from.clear @downstream_from.clear add_vertex(e.source) add_vertex(e.target) @in_to[ e.target][e.source] ||= []; @in_to[ e.target][e.source] |= [e] @out_from[e.source][e.target] ||= []; @out_from[e.source][e.target] |= [e] end def add_relationship(source, target, label = nil) add_edge Puppet::Relationship.new(source, target, label) end # Find all matching edges. def edges_between(source, target) (@out_from[source] || {})[target] || [] end # Is there an edge between the two vertices? def edge?(source, target) vertex?(source) and vertex?(target) and @out_from[source][target] end def edges @in_to.values.collect { |x| x.values }.flatten end def each_edge @in_to.each { |t,ns| ns.each { |s,es| es.each { |e| yield e }}} end # Remove an edge from our graph. def remove_edge!(e) if edge?(e.source,e.target) @upstream_from.clear @downstream_from.clear @in_to [e.target].delete e.source if (@in_to [e.target][e.source] -= [e]).empty? @out_from[e.source].delete e.target if (@out_from[e.source][e.target] -= [e]).empty? end end # Find adjacent edges. def adjacent(v, options = {}) return [] unless ns = (options[:direction] == :in) ? @in_to[v] : @out_from[v] (options[:type] == :edges) ? ns.values.flatten : ns.keys end # Just walk the tree and pass each edge. def walk(source, direction) # Use an iterative, breadth-first traversal of the graph. One could do # this recursively, but Ruby's slow function calls and even slower # recursion make the shorter, recursive algorithm cost-prohibitive. stack = [source] seen = Set.new until stack.empty? node = stack.shift next if seen.member? node connected = adjacent(node, :direction => direction) connected.each do |target| yield node, target end stack.concat(connected) seen << node end end # A different way of walking a tree, and a much faster way than the # one that comes with GRATR. def tree_from_vertex(start, direction = :out) predecessor={} walk(start, direction) do |parent, child| predecessor[child] = parent end predecessor end def downstream_from_vertex(v) return @downstream_from[v] if @downstream_from[v] result = @downstream_from[v] = {} @out_from[v].keys.each do |node| result[node] = 1 result.update(downstream_from_vertex(node)) end result end def direct_dependents_of(v) (@out_from[v] || {}).keys end def upstream_from_vertex(v) return @upstream_from[v] if @upstream_from[v] result = @upstream_from[v] = {} @in_to[v].keys.each do |node| result[node] = 1 result.update(upstream_from_vertex(node)) end result end def direct_dependencies_of(v) (@in_to[v] || {}).keys end # Return an array of the edge-sets between a series of n+1 vertices (f=v0,v1,v2...t=vn) # connecting the two given verticies. The ith edge set is an array containing all the # edges between v(i) and v(i+1); these are (by definition) never empty. # # * if f == t, the list is empty # * if they are adjacent the result is an array consisting of # a single array (the edges from f to t) # * and so on by induction on a vertex m between them # * if there is no path from f to t, the result is nil # # This implementation is not particularly efficient; it's used in testing where clarity # is more important than last-mile efficiency. # def path_between(f,t) if f==t [] elsif direct_dependents_of(f).include?(t) [edges_between(f,t)] elsif dependents(f).include?(t) m = (dependents(f) & direct_dependencies_of(t)).first path_between(f,m) + path_between(m,t) else nil end end # LAK:FIXME This is just a paste of the GRATR code with slight modifications. # Return a DOT::DOTDigraph for directed graphs or a DOT::DOTSubgraph for an # undirected Graph. _params_ can contain any graph property specified in # rdot.rb. If an edge or vertex label is a kind of Hash then the keys # which match +dot+ properties will be used as well. def to_dot_graph (params = {}) params['name'] ||= self.class.name.gsub(/:/,'_') fontsize = params['fontsize'] ? params['fontsize'] : '8' graph = (directed? ? DOT::DOTDigraph : DOT::DOTSubgraph).new(params) edge_klass = directed? ? DOT::DOTDirectedEdge : DOT::DOTEdge vertices.each do |v| name = v.to_s params = {'name' => '"'+name+'"', 'fontsize' => fontsize, 'label' => name} v_label = v.to_s params.merge!(v_label) if v_label and v_label.kind_of? Hash graph << DOT::DOTNode.new(params) end edges.each do |e| params = {'from' => '"'+ e.source.to_s + '"', 'to' => '"'+ e.target.to_s + '"', 'fontsize' => fontsize } e_label = e.to_s params.merge!(e_label) if e_label and e_label.kind_of? Hash graph << edge_klass.new(params) end graph end # Output the dot format as a string def to_dot (params={}) to_dot_graph(params).to_s; end # Call +dotty+ for the graph which is written to the file 'graph.dot' # in the # current directory. def dotty (params = {}, dotfile = 'graph.dot') File.open(dotfile, 'w') {|f| f << to_dot(params) } system('dotty', dotfile) end # Produce the graph files if requested. def write_graph(name) return unless Puppet[:graph] Puppet.settings.use(:graphing) file = File.join(Puppet[:graphdir], "#{name}.dot") File.open(file, "w") { |f| f.puts to_dot("name" => name.to_s.capitalize) } end # This flag may be set to true to use the new YAML serialzation # format (where @vertices is a simple list of vertices rather than a # list of VertexWrapper objects). Deserialization supports both # formats regardless of the setting of this flag. class << self attr_accessor :use_new_yaml_format end self.use_new_yaml_format = false # Stub class to allow graphs to be represented in YAML using the old # (version 2.6) format. class VertexWrapper attr_reader :vertex, :adjacencies def initialize(vertex, adjacencies) @vertex = vertex @adjacencies = adjacencies end def inspect { :@adjacencies => @adjacencies, :@vertex => @vertex.to_s }.inspect end end # instance_variable_get is used by Object.to_zaml to get instance # variables. Override it so that we can simulate the presence of # instance variables @edges and @vertices for serialization. def instance_variable_get(v) case v.to_s when '@edges' then edges when '@vertices' then if self.class.use_new_yaml_format vertices else result = {} vertices.each do |vertex| adjacencies = {} [:in, :out].each do |direction| adjacencies[direction] = {} adjacent(vertex, :direction => direction, :type => :edges).each do |edge| other_vertex = direction == :in ? edge.source : edge.target (adjacencies[direction][other_vertex] ||= Set.new).add(edge) end end result[vertex] = Puppet::SimpleGraph::VertexWrapper.new(vertex, adjacencies) end result end else super(v) end end def to_yaml_properties - other_vars = instance_variables. - map {|v| v.to_s}. - reject { |v| %w{@in_to @out_from @upstream_from @downstream_from}.include?(v) } - - (other_vars + %w{@vertices @edges}).sort.uniq + (instance_variables + [:@vertices, :@edges] - + [:@in_to, :@out_from, :@upstream_from, :@downstream_from]).sort.uniq end def yaml_initialize(tag, var) initialize() vertices = var.delete('vertices') edges = var.delete('edges') if vertices.is_a?(Hash) # Support old (2.6) format vertices = vertices.keys end vertices.each { |v| add_vertex(v) } edges.each { |e| add_edge(e) } var.each do |varname, value| instance_variable_set("@#{varname}", value) end end end diff --git a/lib/puppet/transaction/event.rb b/lib/puppet/transaction/event.rb index d3f25b71c..5e4a8eb50 100644 --- a/lib/puppet/transaction/event.rb +++ b/lib/puppet/transaction/event.rb @@ -1,66 +1,73 @@ require 'puppet/transaction' require 'puppet/util/tagging' require 'puppet/util/logging' # A simple struct for storing what happens on the system. class Puppet::Transaction::Event include Puppet::Util::Tagging include Puppet::Util::Logging ATTRIBUTES = [:name, :resource, :property, :previous_value, :desired_value, :historical_value, :status, :message, :file, :line, :source_description, :audited] - YAML_ATTRIBUTES = %w{@audited @property @previous_value @desired_value @historical_value @message @name @status @time} + YAML_ATTRIBUTES = %w{@audited @property @previous_value @desired_value @historical_value @message @name @status @time}.map(&:to_sym) attr_accessor *ATTRIBUTES attr_writer :tags attr_accessor :time attr_reader :default_log_level EVENT_STATUSES = %w{noop success failure audit} def initialize(options = {}) @audited = false options.each { |attr, value| send(attr.to_s + "=", value) } @time = Time.now end def property=(prop) @property = prop.to_s end def resource=(res) - if res.respond_to?(:[]) and level = res[:loglevel] - @default_log_level = level + begin + # In Ruby 1.8 looking up a symbol on a string gives nil; in 1.9 it will + # raise a TypeError, which we then catch. This should work on both + # versions, for all that it is a bit naff. --daniel 2012-03-11 + if res.respond_to?(:[]) and level = res[:loglevel] + @default_log_level = level + end + rescue TypeError => e + raise unless e.to_s == "can't convert Symbol into Integer" end @resource = res.to_s end def send_log super(log_level, message) end def status=(value) raise ArgumentError, "Event status can only be #{EVENT_STATUSES.join(', ')}" unless EVENT_STATUSES.include?(value) @status = value end def to_s message end def to_yaml_properties - (YAML_ATTRIBUTES.map {|ya| ya.to_s} & instance_variables.map{|iv| iv.to_s}).sort + (YAML_ATTRIBUTES & instance_variables).sort end private # If it's a failure, use 'err', else use either the resource's log level (if available) # or 'notice'. def log_level status == "failure" ? :err : (@default_log_level || :notice) end # Used by the Logging module def log_source source_description || property || resource end end diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb index b7a0341b1..7c9ffe811 100644 --- a/lib/puppet/transaction/report.rb +++ b/lib/puppet/transaction/report.rb @@ -1,200 +1,200 @@ require 'puppet' require 'puppet/indirector' # A class for reporting what happens on each client. Reports consist of # two types of data: Logs and Metrics. Logs are the output that each # change produces, and Metrics are all of the numerical data involved # in the transaction. class Puppet::Transaction::Report extend Puppet::Indirector indirects :report, :terminus_class => :processor attr_accessor :configuration_version, :host, :environment attr_reader :resource_statuses, :logs, :metrics, :time, :kind, :status # This is necessary since Marshall doesn't know how to # dump hash with default proc (see below @records) def self.default_format :yaml end def <<(msg) @logs << msg self end def add_times(name, value) @external_times[name] = value end def add_metric(name, hash) metric = Puppet::Util::Metric.new(name) hash.each do |name, value| metric.newvalue(name, value) end @metrics[metric.name] = metric metric end def add_resource_status(status) @resource_statuses[status.resource] = status end def compute_status(resource_metrics, change_metric) if (resource_metrics["failed"] || 0) > 0 'failed' elsif change_metric > 0 'changed' else 'unchanged' end end def prune_internal_data resource_statuses.delete_if {|name,res| res.resource_type == 'Whit'} end def finalize_report prune_internal_data resource_metrics = add_metric(:resources, calculate_resource_metrics) add_metric(:time, calculate_time_metrics) change_metric = calculate_change_metric add_metric(:changes, {"total" => change_metric}) add_metric(:events, calculate_event_metrics) @status = compute_status(resource_metrics, change_metric) end def initialize(kind, configuration_version=nil, environment=nil) @metrics = {} @logs = [] @resource_statuses = {} @external_times ||= {} @host = Puppet[:node_name_value] @time = Time.now @kind = kind @report_format = 2 @puppet_version = Puppet.version @configuration_version = configuration_version @environment = environment @status = 'failed' # assume failed until the report is finalized end def name host end # Provide a human readable textual summary of this report. def summary report = raw_summary ret = "" report.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |key| ret += "#{Puppet::Util::Metric.labelize(key)}:\n" report[key].keys.sort { |a,b| # sort by label if a == :total 1 elsif b == :total -1 else report[key][a].to_s <=> report[key][b].to_s end }.each do |label| value = report[key][label] next if value == 0 value = "%0.2f" % value if value.is_a?(Float) ret += " %15s %s\n" % [Puppet::Util::Metric.labelize(label) + ":", value] end end ret end # Provide a raw hash summary of this report. def raw_summary report = { "version" => { "config" => configuration_version, "puppet" => Puppet.version } } @metrics.each do |name, metric| key = metric.name.to_s report[key] = {} metric.values.each do |name, label, value| report[key][name.to_s] = value end report[key]["total"] = 0 unless key == "time" or report[key].include?("total") end (report["time"] ||= {})["last_run"] = Time.now.tv_sec report end # Based on the contents of this report's metrics, compute a single number # that represents the report. The resulting number is a bitmask where # individual bits represent the presence of different metrics. def exit_status status = 0 status |= 2 if @metrics["changes"]["total"] > 0 status |= 4 if @metrics["resources"]["failed"] > 0 status end def to_yaml_properties - (instance_variables - ["@external_times"]).sort + (instance_variables - [:@external_times]).sort end private def calculate_change_metric resource_statuses.map { |name, status| status.change_count || 0 }.inject(0) { |a,b| a+b } end def calculate_event_metrics metrics = Hash.new(0) %w{total failure success}.each { |m| metrics[m] = 0 } resource_statuses.each do |name, status| metrics["total"] += status.events.length status.events.each do |event| metrics[event.status] += 1 end end metrics end def calculate_resource_metrics metrics = {} metrics["total"] = resource_statuses.length # force every resource key in the report to be present # even if no resources is in this given state Puppet::Resource::Status::STATES.each do |state| metrics[state.to_s] = 0 end resource_statuses.each do |name, status| Puppet::Resource::Status::STATES.each do |state| metrics[state.to_s] += 1 if status.send(state) end end metrics end def calculate_time_metrics metrics = Hash.new(0) resource_statuses.each do |name, status| type = Puppet::Resource.new(name).type metrics[type.to_s.downcase] += status.evaluation_time if status.evaluation_time end @external_times.each do |name, value| metrics[name.to_s.downcase] = value end metrics["total"] = metrics.values.inject(0) { |a,b| a+b } metrics end end diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb index 224e79731..1c465e9d1 100755 --- a/lib/puppet/type/tidy.rb +++ b/lib/puppet/type/tidy.rb @@ -1,333 +1,324 @@ Puppet::Type.newtype(:tidy) do require 'puppet/file_serving/fileset' require 'puppet/file_bucket/dipper' @doc = "Remove unwanted files based on specific criteria. Multiple criteria are OR'd together, so a file that is too large but is not old enough will still get tidied. If you don't specify either `age` or `size`, then all files will be removed. This resource type works by generating a file resource for every file that should be deleted and then letting that resource perform the actual deletion. " newparam(:path) do desc "The path to the file or directory to manage. Must be fully qualified." isnamevar end newparam(:recurse) do desc "If target is a directory, recursively descend into the directory looking for files to tidy." newvalues(:true, :false, :inf, /^[0-9]+$/) # Replace the validation so that we allow numbers in # addition to string representations of them. validate { |arg| } munge do |value| newval = super(value) case newval when :true, :inf; true when :false; false when Integer, Fixnum, Bignum; value when /^\d+$/; Integer(value) else raise ArgumentError, "Invalid recurse value #{value.inspect}" end end end newparam(:matches) do desc <<-EOT One or more (shell type) file glob patterns, which restrict the list of files to be tidied to those whose basenames match at least one of the patterns specified. Multiple patterns can be specified using an array. Example: tidy { "/tmp": age => "1w", recurse => 1, matches => [ "[0-9]pub*.tmp", "*.temp", "tmpfile?" ] } This removes files from `/tmp` if they are one week old or older, are not in a subdirectory and match one of the shell globs given. Note that the patterns are matched against the basename of each file -- that is, your glob patterns should not have any '/' characters in them, since you are only specifying against the last bit of the file. Finally, note that you must now specify a non-zero/non-false value for recurse if matches is used, as matches only apply to files found by recursion (there's no reason to use static patterns match against a statically determined path). Requiering explicit recursion clears up a common source of confusion. EOT # Make sure we convert to an array. munge do |value| fail "Tidy can't use matches with recurse 0, false, or undef" if "#{@resource[:recurse]}" =~ /^(0|false|)$/ [value].flatten end # Does a given path match our glob patterns, if any? Return true # if no patterns have been provided. def tidy?(path, stat) basename = File.basename(path) flags = File::FNM_DOTMATCH | File::FNM_PATHNAME return(value.find {|pattern| File.fnmatch(pattern, basename, flags) } ? true : false) end end newparam(:backup) do desc "Whether tidied files should be backed up. Any values are passed directly to the file resources used for actual file deletion, so consult the `file` type's backup documentation to determine valid values." end newparam(:age) do desc "Tidy files whose age is equal to or greater than the specified time. You can choose seconds, minutes, hours, days, or weeks by specifying the first letter of any of those words (e.g., '1w'). Specifying 0 will remove all files." - @@ageconvertors = { + AgeConvertors = { :s => 1, - :m => 60 + :m => 60, + :h => 60 * 60, + :d => 60 * 60 * 24, + :w => 60 * 60 * 24 * 7, } - @@ageconvertors[:h] = @@ageconvertors[:m] * 60 - @@ageconvertors[:d] = @@ageconvertors[:h] * 24 - @@ageconvertors[:w] = @@ageconvertors[:d] * 7 - def convert(unit, multi) - if num = @@ageconvertors[unit] + if num = AgeConvertors[unit] return num * multi else self.fail "Invalid age unit '#{unit}'" end end def tidy?(path, stat) # If the file's older than we allow, we should get rid of it. (Time.now.to_i - stat.send(resource[:type]).to_i) > value end munge do |age| unit = multi = nil case age when /^([0-9]+)(\w)\w*$/ multi = Integer($1) unit = $2.downcase.intern when /^([0-9]+)$/ multi = Integer($1) unit = :d else self.fail "Invalid tidy age #{age}" end convert(unit, multi) end end newparam(:size) do desc "Tidy files whose size is equal to or greater than the specified size. Unqualified values are in kilobytes, but *b*, *k*, *m*, *g*, and *t* can be appended to specify *bytes*, *kilobytes*, *megabytes*, *gigabytes*, and *terabytes*, respectively. Only the first character is significant, so the full word can also be used." - @@sizeconvertors = { - :b => 0, - :k => 1, - :m => 2, - :g => 3, - :t => 4 - } - def convert(unit, multi) - if num = @@sizeconvertors[unit] + if num = { :b => 0, :k => 1, :m => 2, :g => 3, :t => 4 }[unit] result = multi num.times do result *= 1024 end return result else self.fail "Invalid size unit '#{unit}'" end end def tidy?(path, stat) stat.size >= value end munge do |size| case size when /^([0-9]+)(\w)\w*$/ multi = Integer($1) unit = $2.downcase.intern when /^([0-9]+)$/ multi = Integer($1) unit = :k else self.fail "Invalid tidy size #{age}" end convert(unit, multi) end end newparam(:type) do desc "Set the mechanism for determining age." newvalues(:atime, :mtime, :ctime) defaultto :atime end newparam(:rmdirs, :boolean => true) do desc "Tidy directories in addition to files; that is, remove directories whose age is older than the specified criteria. This will only remove empty directories, so all contained files must also be tidied before a directory gets removed." newvalues :true, :false end # Erase PFile's validate method validate do end def self.instances [] end def depthfirst? true end def initialize(hash) super # only allow backing up into filebuckets self[:backup] = false unless self[:backup].is_a? Puppet::FileBucket::Dipper end # Make a file resource to remove a given file. def mkfile(path) # Force deletion, so directories actually get deleted. Puppet::Type.type(:file).new :path => path, :backup => self[:backup], :ensure => :absent, :force => true end def retrieve # Our ensure property knows how to retrieve everything for us. if obj = @parameters[:ensure] return obj.retrieve else return {} end end # Hack things a bit so we only ever check the ensure property. def properties [] end def generate return [] unless stat(self[:path]) case self[:recurse] when Integer, Fixnum, Bignum, /^\d+$/ parameter = { :recurse => true, :recurselimit => self[:recurse] } when true, :true, :inf parameter = { :recurse => true } end if parameter files = Puppet::FileServing::Fileset.new(self[:path], parameter).files.collect do |f| f == "." ? self[:path] : ::File.join(self[:path], f) end else files = [self[:path]] end result = files.find_all { |path| tidy?(path) }.collect { |path| mkfile(path) }.each { |file| notice "Tidying #{file.ref}" }.sort { |a,b| b[:path] <=> a[:path] } # No need to worry about relationships if we don't have rmdirs; there won't be # any directories. return result unless rmdirs? # Now make sure that all directories require the files they contain, if all are available, # so that a directory is emptied before we try to remove it. files_by_name = result.inject({}) { |hash, file| hash[file[:path]] = file; hash } files_by_name.keys.sort { |a,b| b <=> b }.each do |path| dir = ::File.dirname(path) next unless resource = files_by_name[dir] if resource[:require] resource[:require] << Puppet::Resource.new(:file, path) else resource[:require] = [Puppet::Resource.new(:file, path)] end end result end # Does a given path match our glob patterns, if any? Return true # if no patterns have been provided. def matches?(path) return true unless self[:matches] basename = File.basename(path) flags = File::FNM_DOTMATCH | File::FNM_PATHNAME if self[:matches].find {|pattern| File.fnmatch(pattern, basename, flags) } return true else debug "No specified patterns match #{path}, not tidying" return false end end # Should we remove the specified file? def tidy?(path) return false unless stat = self.stat(path) return false if stat.ftype == "directory" and ! rmdirs? # The 'matches' parameter isn't OR'ed with the other tests -- # it's just used to reduce the list of files we can match. return false if param = parameter(:matches) and ! param.tidy?(path, stat) tested = false [:age, :size].each do |name| next unless param = parameter(name) tested = true return true if param.tidy?(path, stat) end # If they don't specify either, then the file should always be removed. return true unless tested false end def stat(path) begin ::File.lstat(path) rescue Errno::ENOENT => error info "File does not exist" return nil rescue Errno::EACCES => error warning "Could not stat; permission denied" return nil end end end diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index 736c1a96b..9d1e56367 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -1,508 +1,520 @@ # A module to collect utility functions. require 'English' -require 'puppet/util/monkey_patches' require 'puppet/external/lock' require 'puppet/error' require 'puppet/util/execution_stub' require 'uri' require 'sync' require 'monitor' require 'tempfile' require 'pathname' module Puppet - module Util + require 'puppet/util/monkey_patches' require 'benchmark' # These are all for backward compatibility -- these are methods that used # to be in Puppet::Util but have been moved into external modules. require 'puppet/util/posix' extend Puppet::Util::POSIX @@sync_objects = {}.extend MonitorMixin def self.activerecord_version if (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR)) ([::ActiveRecord::VERSION::MAJOR, ::ActiveRecord::VERSION::MINOR].join('.').to_f) else 0 end end # Run some code with a specific environment. Resets the environment back to # what it was at the end of the code. def self.withenv(hash) saved = ENV.to_hash hash.each do |name, val| ENV[name.to_s] = val end yield ensure ENV.clear saved.each do |name, val| ENV[name] = val end end # Execute a given chunk of code with a new umask. def self.withumask(mask) cur = File.umask(mask) begin yield ensure File.umask(cur) end end def self.synchronize_on(x,type) sync_object,users = 0,1 begin @@sync_objects.synchronize { (@@sync_objects[x] ||= [Sync.new,0])[users] += 1 } @@sync_objects[x][sync_object].synchronize(type) { yield } ensure @@sync_objects.synchronize { @@sync_objects.delete(x) unless (@@sync_objects[x][users] -= 1) > 0 } end end # Change the process to a different user def self.chuser if group = Puppet[:group] begin Puppet::Util::SUIDManager.change_group(group, true) rescue => detail Puppet.warning "could not change to group #{group.inspect}: #{detail}" $stderr.puts "could not change to group #{group.inspect}" # Don't exit on failed group changes, since it's # not fatal #exit(74) end end if user = Puppet[:user] begin Puppet::Util::SUIDManager.change_user(user, true) rescue => detail $stderr.puts "Could not change to user #{user}: #{detail}" exit(74) end end end # Create instance methods for each of the log levels. This allows # the messages to be a little richer. Most classes will be calling this # method. def self.logmethods(klass, useself = true) Puppet::Util::Log.eachlevel { |level| klass.send(:define_method, level, proc { |args| args = args.join(" ") if args.is_a?(Array) if useself Puppet::Util::Log.create( :level => level, :source => self, :message => args ) else Puppet::Util::Log.create( :level => level, :message => args ) end }) } end # Proxy a bunch of methods to another object. def self.classproxy(klass, objmethod, *methods) classobj = class << klass; self; end methods.each do |method| classobj.send(:define_method, method) do |*args| obj = self.send(objmethod) obj.send(method, *args) end end end # Proxy a bunch of methods to another object. def self.proxy(klass, objmethod, *methods) methods.each do |method| klass.send(:define_method, method) do |*args| obj = self.send(objmethod) obj.send(method, *args) end end end def benchmark(*args) msg = args.pop level = args.pop object = nil if args.empty? if respond_to?(level) object = self else object = Puppet end else object = args.pop end raise Puppet::DevError, "Failed to provide level to :benchmark" unless level unless level == :none or object.respond_to? level raise Puppet::DevError, "Benchmarked object does not respond to #{level}" end # Only benchmark if our log level is high enough if level != :none and Puppet::Util::Log.sendlevel?(level) result = nil seconds = Benchmark.realtime { yield } object.send(level, msg + (" in %0.2f seconds" % seconds)) return seconds else yield end end def which(bin) if absolute_path?(bin) return bin if FileTest.file? bin and FileTest.executable? bin else ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir| begin dest = File.expand_path(File.join(dir, bin)) rescue ArgumentError => e # if the user's PATH contains a literal tilde (~) character and HOME is not set, we may get # an ArgumentError here. Let's check to see if that is the case; if not, re-raise whatever error # was thrown. raise e unless ((dir =~ /~/) && ((ENV['HOME'].nil? || ENV['HOME'] == ""))) # if we get here they have a tilde in their PATH. We'll issue a single warning about this and then # ignore this path element and carry on with our lives. Puppet::Util::Warnings.warnonce("PATH contains a ~ character, and HOME is not set; ignoring PATH element '#{dir}'.") next end if Puppet.features.microsoft_windows? && File.extname(dest).empty? exts = ENV['PATHEXT'] exts = exts ? exts.split(File::PATH_SEPARATOR) : %w[.COM .EXE .BAT .CMD] exts.each do |ext| destext = File.expand_path(dest + ext) return destext if FileTest.file? destext and FileTest.executable? destext end end return dest if FileTest.file? dest and FileTest.executable? dest end end nil end module_function :which # Determine in a platform-specific way whether a path is absolute. This # defaults to the local platform if none is specified. def absolute_path?(path, platform=nil) # Escape once for the string literal, and once for the regex. slash = '[\\\\/]' name = '[^\\\\/]+' regexes = { :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, :posix => %r!^/!, } require 'puppet' platform ||= Puppet.features.microsoft_windows? ? :windows : :posix !! (path =~ regexes[platform]) end module_function :absolute_path? # Convert a path to a file URI def path_to_uri(path) return unless path params = { :scheme => 'file' } if Puppet.features.microsoft_windows? path = path.gsub(/\\/, '/') if unc = /^\/\/([^\/]+)(\/[^\/]+)/.match(path) params[:host] = unc[1] path = unc[2] elsif path =~ /^[a-z]:\//i path = '/' + path end end params[:path] = URI.escape(path) begin URI::Generic.build(params) rescue => detail raise Puppet::Error, "Failed to convert '#{path}' to URI: #{detail}" end end module_function :path_to_uri # Get the path component of a URI def uri_to_path(uri) return unless uri.is_a?(URI) path = URI.unescape(uri.path) if Puppet.features.microsoft_windows? and uri.scheme == 'file' if uri.host path = "//#{uri.host}" + path # UNC else path.sub!(/^\//, '') end end path end module_function :uri_to_path # Create an exclusive lock. def threadlock(resource, type = Sync::EX) Puppet::Util.synchronize_on(resource,type) { yield } end module_function :benchmark def memory unless defined?(@pmap) @pmap = which('pmap') end if @pmap %x{#{@pmap} #{Process.pid}| grep total}.chomp.sub(/^\s*total\s+/, '').sub(/K$/, '').to_i else 0 end end def symbolize(value) if value.respond_to? :intern value.intern else value end end def symbolizehash(hash) newhash = {} hash.each do |name, val| if name.is_a? String newhash[name.intern] = val else newhash[name] = val end end end def symbolizehash!(hash) hash.each do |name, val| if name.is_a? String hash[name.intern] = val hash.delete(name) end end hash end module_function :symbolize, :symbolizehash, :symbolizehash! # Just benchmark, with no logging. def thinmark seconds = Benchmark.realtime { yield } seconds end module_function :memory, :thinmark # Because IO#binread is only available in 1.9 def binread(file) File.open(file, 'rb') { |f| f.read } end module_function :binread # utility method to get the current call stack and format it to a human-readable string (which some IDEs/editors # will recognize as links to the line numbers in the trace) def self.pretty_backtrace(backtrace = caller(1)) backtrace.collect do |line| file_path, line_num = line.split(":") file_path = expand_symlinks(File.expand_path(file_path)) file_path + ":" + line_num end .join("\n") end # utility method that takes a path as input, checks each component of the path to see if it is a symlink, and expands # it if it is. returns the expanded path. def self.expand_symlinks(file_path) file_path.split("/").inject do |full_path, next_dir| next_path = full_path + "/" + next_dir if File.symlink?(next_path) then link = File.readlink(next_path) next_path = case link when /^\// then link else File.expand_path(full_path + "/" + link) end end next_path end end # Replace a file, securely. This takes a block, and passes it the file # handle of a file open for writing. Write the replacement content inside # the block and it will safely replace the target file. # # This method will make no changes to the target file until the content is # successfully written and the block returns without raising an error. # # As far as possible the state of the existing file, such as mode, is # preserved. This works hard to avoid loss of any metadata, but will result # in an inode change for the file. # # Arguments: `filename`, `default_mode` # # The filename is the file we are going to replace. # # The default_mode is the mode to use when the target file doesn't already # exist; if the file is present we copy the existing mode/owner/group values # across. def replace_file(file, default_mode, &block) raise Puppet::DevError, "replace_file requires a block" unless block_given? - raise Puppet::DevError, "replace_file is non-functional on Windows" if Puppet.features.microsoft_windows? file = Pathname(file) tempfile = Tempfile.new(file.basename.to_s, file.dirname.to_s) file_exists = file.exist? # If the file exists, use its current mode/owner/group. If it doesn't, use # the supplied mode, and default to current user/group. if file_exists - stat = file.lstat + if Puppet.features.microsoft_windows? + mode = Puppet::Util::Windows::Security.get_mode(file.to_s) + uid = Puppet::Util::Windows::Security.get_owner(file.to_s) + gid = Puppet::Util::Windows::Security.get_owner(file.to_s) + else + stat = file.lstat + + mode = stat.mode + uid = stat.uid + gid = stat.gid + end # We only care about the four lowest-order octets. Higher octets are # filesystem-specific. - mode = stat.mode & 07777 - uid = stat.uid - gid = stat.gid + mode &= 07777 else mode = default_mode uid = Process.euid gid = Process.egid end # Set properties of the temporary file before we write the content, because # Tempfile doesn't promise to be safe from reading by other people, just # that it avoids races around creating the file. - tempfile.chmod(mode) - tempfile.chown(uid, gid) + if Puppet.features.microsoft_windows? + Puppet::Util::Windows::Security.set_mode(mode, tempfile.path) + Puppet::Util::Windows::Security.set_owner(uid, tempfile.path) + Puppet::Util::Windows::Security.set_group(gid, tempfile.path) + else + tempfile.chmod(mode) + tempfile.chown(uid, gid) + end # OK, now allow the caller to write the content of the file. yield tempfile # Now, make sure the data (which includes the mode) is safe on disk. tempfile.flush begin tempfile.fsync rescue NotImplementedError # fsync may not be implemented by Ruby on all platforms, but # there is absolutely no recovery path if we detect that. So, we just # ignore the return code. # # However, don't be fooled: that is accepting that we are running in # an unsafe fashion. If you are porting to a new platform don't stub # that out. end tempfile.close File.rename(tempfile.path, file) # Ideally, we would now fsync the directory as well, but Ruby doesn't # have support for that, and it doesn't matter /that/ much... # Return something true, and possibly useful. file end module_function :replace_file # Executes a block of code, wrapped with some special exception handling. Causes the ruby interpreter to # exit if the block throws an exception. # # @param [String] message a message to log if the block fails # @param [Integer] code the exit code that the ruby interpreter should return if the block fails # @yield def exit_on_fail(message, code = 1) yield rescue ArgumentError, RuntimeError, NotImplementedError => detail Puppet.log_exception(detail, "Could not #{message}: #{detail}") exit(code) end module_function :exit_on_fail ####################################################################################################### # Deprecated methods relating to process execution; these have been moved to Puppet::Util::Execution ####################################################################################################### def execpipe(command, failonfail = true, &block) Puppet.deprecation_warning("Puppet::Util.execpipe is deprecated; please use Puppet::Util::Execution.execpipe") Puppet::Util::Execution.execpipe(command, failonfail, &block) end module_function :execpipe def execfail(command, exception) Puppet.deprecation_warning("Puppet::Util.execfail is deprecated; please use Puppet::Util::Execution.execfail") Puppet::Util::Execution.execfail(command, exception) end module_function :execfail def execute(command, arguments = {}) Puppet.deprecation_warning("Puppet::Util.execute is deprecated; please use Puppet::Util::Execution.execute") Puppet::Util::Execution.execute(command, arguments) end module_function :execute end end require 'puppet/util/errors' require 'puppet/util/methodhelper' require 'puppet/util/metaid' require 'puppet/util/classgen' require 'puppet/util/docs' require 'puppet/util/execution' require 'puppet/util/logging' require 'puppet/util/package' require 'puppet/util/warnings' diff --git a/lib/puppet/util/execution.rb b/lib/puppet/util/execution.rb index 17247babd..356fb4b6f 100644 --- a/lib/puppet/util/execution.rb +++ b/lib/puppet/util/execution.rb @@ -1,252 +1,254 @@ module Puppet require 'rbconfig' # A command failed to execute. require 'puppet/error' class ExecutionFailure < Puppet::Error end module Util::Execution # Execute the provided command with STDIN connected to a pipe, yielding the # pipe object. That allows data to be fed to that subprocess. # # The command can be a simple string, which is executed as-is, or an Array, # which is treated as a set of command arguments to pass through.# # # In all cases this is passed directly to the shell, and STDOUT and STDERR # are connected together during execution. def self.execpipe(command, failonfail = true) if respond_to? :debug debug "Executing '#{command}'" else Puppet.debug "Executing '#{command}'" end # Paste together an array with spaces. We used to paste directly # together, no spaces, which made for odd invocations; the user had to # include whitespace between arguments. # # Having two spaces is really not a big drama, since this passes to the # shell anyhow, while no spaces makes for a small developer cost every # time this is invoked. --daniel 2012-02-13 command_str = command.respond_to?(:join) ? command.join(' ') : command output = open("| #{command_str} 2>&1") do |pipe| yield pipe end if failonfail unless $CHILD_STATUS == 0 raise ExecutionFailure, output end end output end def self.execfail(command, exception) output = execute(command) return output rescue ExecutionFailure raise exception, output end # Execute the desired command, and return the status and output. # def execute(command, arguments) # [arguments] a Hash optionally containing any of the following keys: # :failonfail (default true) -- if this value is set to true, then this method will raise an error if the # command is not executed successfully. # :uid (default nil) -- the user id of the user that the process should be run as # :gid (default nil) -- the group id of the group that the process should be run as # :combine (default true) -- sets whether or not to combine stdout/stderr in the output # :stdinfile (default nil) -- sets a file that can be used for stdin. Passing a string for stdin is not currently # supported. # :squelch (default false) -- if true, ignore stdout / stderr completely # :override_locale (default true) -- by default (and if this option is set to true), we will temporarily override # the user/system locale to "C" (via environment variables LANG and LC_*) while we are executing the command. # This ensures that the output of the command will be formatted consistently, making it predictable for parsing. # Passing in a value of false for this option will allow the command to be executed using the user/system locale. # :custom_environment (default {}) -- a hash of key/value pairs to set as environment variables for the duration # of the command def self.execute(command, arguments = {}) # specifying these here rather than in the method signature to allow callers to pass in a partial # set of overrides without affecting the default values for options that they don't pass in default_arguments = { :failonfail => true, :uid => nil, :gid => nil, :combine => true, :stdinfile => nil, :squelch => false, :override_locale => true, :custom_environment => {}, } arguments = default_arguments.merge(arguments) if command.is_a?(Array) command = command.flatten.map(&:to_s) str = command.join(" ") elsif command.is_a?(String) str = command end if respond_to? :debug debug "Executing '#{str}'" else Puppet.debug "Executing '#{str}'" end null_file = Puppet.features.microsoft_windows? ? 'NUL' : '/dev/null' stdin = File.open(arguments[:stdinfile] || null_file, 'r') stdout = arguments[:squelch] ? File.open(null_file, 'w') : Tempfile.new('puppet') stderr = arguments[:combine] ? stdout : File.open(null_file, 'w') exec_args = [command, arguments, stdin, stdout, stderr] if execution_stub = Puppet::Util::ExecutionStub.current_value return execution_stub.call(*exec_args) elsif Puppet.features.posix? child_pid = execute_posix(*exec_args) exit_status = Process.waitpid2(child_pid).last.exitstatus elsif Puppet.features.microsoft_windows? process_info = execute_windows(*exec_args) begin exit_status = Puppet::Util::Windows::Process.wait_process(process_info.process_handle) ensure Process.CloseHandle(process_info.process_handle) Process.CloseHandle(process_info.thread_handle) end end [stdin, stdout, stderr].each {|io| io.close rescue nil} # read output in if required unless arguments[:squelch] output = wait_for_output(stdout) Puppet.warning "Could not get output" unless output end if arguments[:failonfail] and exit_status != 0 raise ExecutionFailure, "Execution of '#{str}' returned #{exit_status}: #{output}" end output end - # get the path to the ruby executable (available via Config object, even if it's not in the PATH... so this - # is slightly safer than just using Puppet::Util.which) + # get the path to the ruby executable (available via Config object, even if + # it's not in the PATH... so this is slightly safer than just using + # Puppet::Util.which) def self.ruby_path() - File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'] + Config::CONFIG['EXEEXT']). - sub(/.*\s.*/m, '"\&"') + File.join(RbConfig::CONFIG['bindir'], + RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']). + sub(/.*\s.*/m, '"\&"') end # Because some modules provide their own version of this method. class << self alias util_execute execute end # this is private method, see call to private_class_method after method definition def self.execute_posix(command, arguments, stdin, stdout, stderr) child_pid = Kernel.fork do # We can't just call Array(command), and rely on it returning # things like ['foo'], when passed ['foo'], because # Array(command) will call command.to_a internally, which when # given a string can end up doing Very Bad Things(TM), such as # turning "/tmp/foo;\r\n /bin/echo" into ["/tmp/foo;\r\n", " /bin/echo"] command = [command].flatten Process.setsid begin $stdin.reopen(stdin) $stdout.reopen(stdout) $stderr.reopen(stderr) # we are in a forked process, so we currently have access to all of the file descriptors # from the parent process... which, in this case, is bad because we don't want # to allow the user's command to have access to them. Therefore, we'll close them off. # (assumes that there are only 256 file descriptors used) 3.upto(256){|fd| IO::new(fd).close rescue nil} Puppet::Util::SUIDManager.change_privileges(arguments[:uid], arguments[:gid], true) # if the caller has requested that we override locale environment variables, if (arguments[:override_locale]) then # loop over them and clear them Puppet::Util::POSIX::LOCALE_ENV_VARS.each { |name| ENV.delete(name) } # set LANG and LC_ALL to 'C' so that the command will have consistent, predictable output # it's OK to manipulate these directly rather than, e.g., via "withenv", because we are in # a forked process. ENV['LANG'] = 'C' ENV['LC_ALL'] = 'C' end # unset all of the user-related environment variables so that different methods of starting puppet # (automatic start during boot, via 'service', via /etc/init.d, etc.) won't have unexpected side # effects relating to user / home dir environment vars. # it's OK to manipulate these directly rather than, e.g., via "withenv", because we are in # a forked process. Puppet::Util::POSIX::USER_ENV_VARS.each { |name| ENV.delete(name) } arguments[:custom_environment] ||= {} Puppet::Util.withenv(arguments[:custom_environment]) do Kernel.exec(*command) end rescue => detail Puppet.log_exception(detail, "Could not execute posix command: #{detail}") exit!(1) end end child_pid end private_class_method :execute_posix # this is private method, see call to private_class_method after method definition def self.execute_windows(command, arguments, stdin, stdout, stderr) command = command.map do |part| part.include?(' ') ? %Q["#{part.gsub(/"/, '\"')}"] : part end.join(" ") if command.is_a?(Array) arguments[:custom_environment] ||= {} Puppet::Util.withenv(arguments[:custom_environment]) do Puppet::Util::Windows::Process.execute(command, arguments, stdin, stdout, stderr) end end private_class_method :execute_windows # this is private method, see call to private_class_method after method definition def self.wait_for_output(stdout) # Make sure the file's actually been written. This is basically a race # condition, and is probably a horrible way to handle it, but, well, oh # well. # (If this method were treated as private / inaccessible from outside of this file, we shouldn't have to worry # about a race condition because all of the places that we call this from are preceded by a call to "waitpid2", # meaning that the processes responsible for writing the file have completed before we get here.) 2.times do |try| if File.exists?(stdout.path) output = stdout.open.read stdout.close(true) return output else time_to_sleep = try / 2.0 Puppet.warning "Waiting for output; will sleep #{time_to_sleep} seconds" sleep(time_to_sleep) end end nil end private_class_method :wait_for_output end end diff --git a/lib/puppet/util/file_locking.rb b/lib/puppet/util/file_locking.rb deleted file mode 100644 index 18744cab7..000000000 --- a/lib/puppet/util/file_locking.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'puppet/util' - -module Puppet::Util::FileLocking - module_function - - # Create a shared lock for reading - def readlock(file) - raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file) - Puppet::Util.synchronize_on(file,Sync::SH) do - File.open(file) { |f| - f.lock_shared { |lf| yield lf } - } - end - end - - # Create an exclusive lock for writing, and do the writing in a - # tmp file. - def writelock(file, mode = nil) - raise Puppet::DevError, "Cannot create #{file}; directory #{File.dirname(file)} does not exist" unless FileTest.directory?(File.dirname(file)) - raise ArgumentError, "#{file} is not a file" unless !File.exists?(file) or File.file?(file) - tmpfile = file + ".tmp" - - unless mode - # It's far more likely that the file will be there than not, so it's - # better to stat once to check for existence and mode. - # If we can't stat, it's most likely because the file's not there, - # but could also be because the directory isn't readable, in which case - # we won't be able to write anyway. - begin - mode = File.stat(file).mode - rescue - mode = 0600 - end - end - - Puppet::Util.synchronize_on(file,Sync::EX) do - File.open(file, File::Constants::CREAT | File::Constants::WRONLY, mode) do |rf| - rf.lock_exclusive do |lrf| - # poor's man open(2) O_EXLOCK|O_TRUNC - lrf.seek(0, IO::SEEK_SET) - lrf.truncate(0) - yield lrf - end - end - end - end -end diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb index c67d0e93f..41839b106 100644 --- a/lib/puppet/util/log.rb +++ b/lib/puppet/util/log.rb @@ -1,273 +1,274 @@ require 'puppet/util/tagging' require 'puppet/util/classgen' # Pass feedback to the user. Log levels are modeled after syslog's, and it is # expected that that will be the most common log destination. Supports # multiple destinations, one of which is a remote server. class Puppet::Util::Log include Puppet::Util extend Puppet::Util::ClassGen include Puppet::Util::Tagging @levels = [:debug,:info,:notice,:warning,:err,:alert,:emerg,:crit] @loglevel = 2 @desttypes = {} # Create a new destination type. def self.newdesttype(name, options = {}, &block) dest = genclass( name, :parent => Puppet::Util::Log::Destination, :prefix => "Dest", :block => block, :hash => @desttypes, :attributes => options ) dest.match(dest.name) dest end require 'puppet/util/log/destination' require 'puppet/util/log/destinations' @destinations = {} @queued = [] class << self include Puppet::Util include Puppet::Util::ClassGen attr_reader :desttypes end # Reset log to basics. Basically just flushes and closes files and # undefs other objects. def Log.close(destination) if @destinations.include?(destination) @destinations[destination].flush if @destinations[destination].respond_to?(:flush) @destinations[destination].close if @destinations[destination].respond_to?(:close) @destinations.delete(destination) end end def self.close_all destinations.keys.each { |dest| close(dest) } raise Puppet::DevError.new("Log.close_all failed to close #{@destinations.keys.inspect}") if !@destinations.empty? end # Flush any log destinations that support such operations. def Log.flush @destinations.each { |type, dest| dest.flush if dest.respond_to?(:flush) } end def Log.autoflush=(v) @destinations.each do |type, dest| dest.autoflush = v if dest.respond_to?(:autoflush=) end end # Create a new log message. The primary role of this method is to # avoid creating log messages below the loglevel. def Log.create(hash) raise Puppet::DevError, "Logs require a level" unless hash.include?(:level) raise Puppet::DevError, "Invalid log level #{hash[:level]}" unless @levels.index(hash[:level]) @levels.index(hash[:level]) >= @loglevel ? Puppet::Util::Log.new(hash) : nil end def Log.destinations @destinations end # Yield each valid level in turn def Log.eachlevel @levels.each { |level| yield level } end # Return the current log level. def Log.level @levels[@loglevel] end # Set the current log level. def Log.level=(level) level = level.intern unless level.is_a?(Symbol) raise Puppet::DevError, "Invalid loglevel #{level}" unless @levels.include?(level) @loglevel = @levels.index(level) end def Log.levels @levels.dup end # Create a new log destination. def Log.newdestination(dest) # Each destination can only occur once. if @destinations.find { |name, obj| obj.name == dest } return end name, type = @desttypes.find do |name, klass| klass.match?(dest) end if type.respond_to?(:suitable?) and not type.suitable?(dest) return end raise Puppet::DevError, "Unknown destination type #{dest}" unless type begin if type.instance_method(:initialize).arity == 1 @destinations[dest] = type.new(dest) else @destinations[dest] = type.new end flushqueue @destinations[dest] rescue => detail Puppet.log_exception(detail) # If this was our only destination, then add the console back in. newdestination(:console) if @destinations.empty? and (dest != :console and dest != "console") end end # Route the actual message. FIXME There are lots of things this method # should do, like caching and a bit more. It's worth noting that there's # a potential for a loop here, if the machine somehow gets the destination set as # itself. def Log.newmessage(msg) return if @levels.index(msg.level) < @loglevel queuemessage(msg) if @destinations.length == 0 @destinations.each do |name, dest| threadlock(dest) do dest.handle(msg) end end end def Log.queuemessage(msg) @queued.push(msg) end def Log.flushqueue return unless @destinations.size >= 1 @queued.each do |msg| Log.newmessage(msg) end @queued.clear end def Log.sendlevel?(level) @levels.index(level) >= @loglevel end # Reopen all of our logs. def Log.reopen Puppet.notice "Reopening log files" types = @destinations.keys @destinations.each { |type, dest| dest.close if dest.respond_to?(:close) } @destinations.clear # We need to make sure we always end up with some kind of destination begin types.each { |type| Log.newdestination(type) } rescue => detail if @destinations.empty? Log.setup_default Puppet.err detail.to_s end end end def self.setup_default Log.newdestination(Puppet.features.syslog? ? :syslog : Puppet[:puppetdlog]) end # Is the passed level a valid log level? def self.validlevel?(level) @levels.include?(level) end attr_accessor :time, :remote, :file, :line, :source attr_reader :level, :message def initialize(args) self.level = args[:level] self.message = args[:message] self.source = args[:source] || "Puppet" @time = Time.now if tags = args[:tags] tags.each { |t| self.tag(t) } end [:file, :line].each do |attr| next unless value = args[attr] send(attr.to_s + "=", value) end Log.newmessage(self) end def message=(msg) raise ArgumentError, "Puppet::Util::Log requires a message" unless msg @message = msg.to_s end def level=(level) raise ArgumentError, "Puppet::Util::Log requires a log level" unless level + raise ArgumentError, "Puppet::Util::Log requires a symbol or string" unless level.respond_to? "to_sym" @level = level.to_sym raise ArgumentError, "Invalid log level #{@level}" unless self.class.validlevel?(@level) # Tag myself with my log level tag(level) end # If they pass a source in to us, we make sure it is a string, and # we retrieve any tags we can. def source=(source) if source.respond_to?(:source_descriptors) descriptors = source.source_descriptors @source = descriptors[:path] descriptors[:tags].each { |t| tag(t) } [:file, :line].each do |param| next unless descriptors[param] send(param.to_s + "=", descriptors[param]) end else @source = source.to_s end end def to_report "#{time} #{source} (#{level}): #{to_s}" end def to_s message end end # This is for backward compatibility from when we changed the constant to Puppet::Util::Log # because the reports include the constant name. Apparently the alias was created in # March 2007, should could probably be removed soon. Puppet::Log = Puppet::Util::Log diff --git a/lib/puppet/util/monkey_patches.rb b/lib/puppet/util/monkey_patches.rb index 010e9b1d3..952aa2790 100644 --- a/lib/puppet/util/monkey_patches.rb +++ b/lib/puppet/util/monkey_patches.rb @@ -1,172 +1,230 @@ +require 'puppet/util' +module Puppet::Util::MonkeyPatches +end unless defined? JRUBY_VERSION Process.maxgroups = 1024 end module RDoc def self.caller(skip=nil) in_gem_wrapper = false Kernel.caller.reject { |call| in_gem_wrapper ||= call =~ /#{Regexp.escape $0}:\d+:in `load'/ } end end require "yaml" require "puppet/util/zaml.rb" class Symbol def to_zaml(z) z.emit("!ruby/sym ") to_s.to_zaml(z) end def <=> (other) self.to_s <=> other.to_s - end + end unless method_defined? "<=>" end [Object, Exception, Integer, Struct, Date, Time, Range, Regexp, Hash, Array, Float, String, FalseClass, TrueClass, Symbol, NilClass, Class].each { |cls| cls.class_eval do def to_yaml(ignored=nil) ZAML.dump(self) end end } def YAML.dump(*args) ZAML.dump(*args) end # # Workaround for bug in MRI 1.8.7, see # http://redmine.ruby-lang.org/issues/show/2708 # for details # if RUBY_VERSION == '1.8.7' class NilClass def closed? true end end end class Object # ActiveSupport 2.3.x mixes in a dangerous method # that can cause rspec to fork bomb # and other strange things like that. def daemonize raise NotImplementedError, "Kernel.daemonize is too dangerous, please don't try to use it." end - - # The following code allows callers to make assertions that are only - # checked when the environment variable PUPPET_ENABLE_ASSERTIONS is - # set to a non-empty string. For example: - # - # assert_that { condition } - # assert_that(message) { condition } - if ENV["PUPPET_ENABLE_ASSERTIONS"].to_s != '' - def assert_that(message = nil) - unless yield - raise Exception.new("Assertion failure: #{message}") - end - end - else - def assert_that(message = nil) - end - end end # Workaround for yaml_initialize, which isn't supported before Ruby # 1.8.3. if RUBY_VERSION == '1.8.1' || RUBY_VERSION == '1.8.2' YAML.add_ruby_type( /^object/ ) { |tag, val| type, obj_class = YAML.read_type_class( tag, Object ) r = YAML.object_maker( obj_class, val ) if r.respond_to? :yaml_initialize r.instance_eval { instance_variables.each { |name| remove_instance_variable name } } r.yaml_initialize(tag, val) end r } end class Array # Ruby < 1.8.7 doesn't have this method but we use it in tests def combination(num) return [] if num < 0 || num > size return [[]] if num == 0 return map{|e| [e] } if num == 1 tmp = self.dup self[0, size - (num - 1)].inject([]) do |ret, e| tmp.shift ret += tmp.combination(num - 1).map{|a| a.unshift(e) } end end unless method_defined? :combination alias :count :length unless method_defined? :count end class Symbol def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } end unless method_defined? :to_proc -end + # Defined in 1.9, absent in 1.8, and used for compatibility in various + # places, typically in third party gems. + def intern + return self + end unless method_defined? :intern +end class String - def lines(separator = $/) - lines = split(separator) - block_given? and lines.each {|line| yield line } - lines + unless method_defined? :lines + require 'puppet/util/monkey_patches/lines' + include Puppet::Util::MonkeyPatches::Lines end end +require 'fcntl' class IO - def lines(separator = $/) - lines = split(separator) - block_given? and lines.each {|line| yield line } - lines + unless method_defined? :lines + require 'puppet/util/monkey_patches/lines' + include Puppet::Util::MonkeyPatches::Lines end def self.binread(name, length = nil, offset = 0) File.open(name, 'rb') do |f| f.seek(offset) if offset > 0 f.read(length) end end unless singleton_methods.include?(:binread) - def self.binwrite(name, string, offset = 0) - File.open(name, 'wb') do |f| - f.write(offset > 0 ? string[offset..-1] : string) + def self.binwrite(name, string, offset = nil) + # Determine if we should truncate or not. Since the truncate method on a + # file handle isn't implemented on all platforms, safer to do this in what + # looks like the libc interface - which is usually pretty robust. + # --daniel 2012-03-11 + mode = Fcntl::O_CREAT | Fcntl::O_WRONLY | (offset.nil? ? Fcntl::O_TRUNC : 0) + IO.open(IO::sysopen(name, mode)) do |f| + # ...seek to our desired offset, then write the bytes. Don't try to + # seek past the start of the file, eh, because who knows what platform + # would legitimately blow up if we did that. + # + # Double-check the positioning, too, since destroying data isn't my idea + # of a good time. --daniel 2012-03-11 + target = [0, offset.to_i].max + unless (landed = f.sysseek(target, IO::SEEK_SET)) == target + raise "unable to seek to target offset #{target} in #{name}: got to #{landed}" + end + + f.syswrite(string) end end unless singleton_methods.include?(:binwrite) - end class Range def intersection(other) raise ArgumentError, 'value must be a Range' unless other.kind_of?(Range) return unless other === self.first || self === other.first start = [self.first, other.first].max if self.exclude_end? && self.last <= other.last start ... self.last elsif other.exclude_end? && self.last >= other.last start ... other.last else start .. [ self.last, other.last ].min end end unless method_defined? :intersection alias_method :&, :intersection unless method_defined? :& end # Ruby 1.8.5 doesn't have tap module Kernel def tap yield(self) self end unless method_defined?(:tap) end + + +######################################################################## +# The return type of `instance_variables` changes between Ruby 1.8 and 1.9 +# releases; it used to return an array of strings in the form "@foo", but +# now returns an array of symbols in the form :@foo. +# +# Nothing else in the stack cares which form you get - you can pass the +# string or symbol to things like `instance_variable_set` and they will work +# transparently. +# +# Having the same form in all releases of Puppet is a win, though, so we +# pick a unification and enforce than on all releases. That way developers +# who do set math on them (eg: for YAML rendering) don't have to handle the +# distinction themselves. +# +# In the sane tradition, we bring older releases into conformance with newer +# releases, so we return symbols rather than strings, to be more like the +# future versions of Ruby are. +# +# We also carefully support reloading, by only wrapping when we don't +# already have the original version of the method aliased away somewhere. +if RUBY_VERSION[0,3] == '1.8' + unless Object.respond_to?(:puppet_original_instance_variables) + + # Add our wrapper to the method. + class Object + alias :puppet_original_instance_variables :instance_variables + + def instance_variables + puppet_original_instance_variables.map(&:to_sym) + end + end + + # The one place that Ruby 1.8 assumes something about the return format of + # the `instance_variables` method is actually kind of odd, because it uses + # eval to get at instance variables of another object. + # + # This takes the original code and applies replaces instance_eval with + # instance_variable_get through it. All other bugs in the original (such + # as equality depending on the instance variables having the same order + # without any promise from the runtime) are preserved. --daniel 2012-03-11 + require 'resolv' + class Resolv::DNS::Resource + def ==(other) # :nodoc: + return self.class == other.class && + self.instance_variables == other.instance_variables && + self.instance_variables.collect {|name| self.instance_variable_get name} == + other.instance_variables.collect {|name| other.instance_variable_get name} + end + end + end +end diff --git a/lib/puppet/util/monkey_patches/lines.rb b/lib/puppet/util/monkey_patches/lines.rb new file mode 100644 index 000000000..e54e90d86 --- /dev/null +++ b/lib/puppet/util/monkey_patches/lines.rb @@ -0,0 +1,13 @@ +require 'puppet/util/monkey_patches' +require 'enumerator' + +module Puppet::Util::MonkeyPatches::Lines + def lines(separator = $/) + if block_given? + self.each_line(separator) {|line| yield line } + return self + else + return enum_for(:each_line, separator) + end + end +end diff --git a/lib/puppet/util/network_device/cisco/device.rb b/lib/puppet/util/network_device/cisco/device.rb index 09e4e5c6a..588c8504d 100644 --- a/lib/puppet/util/network_device/cisco/device.rb +++ b/lib/puppet/util/network_device/cisco/device.rb @@ -1,257 +1,257 @@ require 'puppet' require 'puppet/util' require 'puppet/util/network_device/base' require 'puppet/util/network_device/ipcalc' require 'puppet/util/network_device/cisco/interface' require 'puppet/util/network_device/cisco/facts' require 'ipaddr' class Puppet::Util::NetworkDevice::Cisco::Device < Puppet::Util::NetworkDevice::Base include Puppet::Util::NetworkDevice::IPCalc attr_accessor :enable_password def initialize(url, options = {}) super(url) @enable_password = options[:enable_password] || parse_enable(@url.query) transport.default_prompt = /[#>]\s?\z/n end def parse_enable(query) return $1 if query =~ /enable=(.*)/ end def command(cmd=nil) Puppet.debug("command #{cmd}") transport.connect login transport.command("terminal length 0") do |out| enable if out =~ />\s?\z/n end find_capabilities out = execute(cmd) if cmd yield self if block_given? transport.close out end def execute(cmd) transport.command(cmd) end def login return if transport.handles_login? if @url.user != '' transport.command(@url.user, :prompt => /^Password:/) else transport.expect(/^Password:/) end transport.command(@url.password) end def enable raise "Can't issue \"enable\" to enter privileged, no enable password set" unless enable_password transport.command("enable", :prompt => /^Password:/) transport.command(enable_password) end def support_vlan_brief? !! @support_vlan_brief end def find_capabilities out = transport.command("sh vlan brief") lines = out.split("\n") lines.shift; lines.pop @support_vlan_brief = ! (lines.first =~ /^%/) end IF={ :FastEthernet => %w{FastEthernet FastEth Fast FE Fa F}, :GigabitEthernet => %w{GigabitEthernet GigEthernet GigEth GE Gi G}, :TenGigabitEthernet => %w{TenGigabitEthernet TE Te}, :Ethernet => %w{Ethernet Eth E}, :Serial => %w{Serial Se S}, :PortChannel => %w{PortChannel Port-Channel Po}, :POS => %w{POS P}, :VLAN => %w{VLAN VL V}, :Loopback => %w{Loopback Loop Lo}, :ATM => %w{ATM AT A}, :Dialer => %w{Dialer Dial Di D}, :VirtualAccess => %w{Virtual-Access Virtual-A Virtual Virt} } def canonalize_ifname(interface) IF.each do |k,ifnames| if found = ifnames.find { |ifname| interface =~ /^#{ifname}\s*\d/i } - interface =~ /^#{found}(.+)\b/i - return "#{k.to_s}#{$1}".gsub(/\s+/,'') + found = /^#{found}(.+)\Z/i.match(interface) + return "#{k.to_s}#{found[1]}".gsub(/\s+/,'') end end interface end def facts @facts ||= Puppet::Util::NetworkDevice::Cisco::Facts.new(transport) facts = {} command do |ng| facts = @facts.retrieve end facts end def interface(name) ifname = canonalize_ifname(name) interface = parse_interface(ifname) return { :ensure => :absent } if interface.empty? interface.merge!(parse_trunking(ifname)) interface.merge!(parse_interface_config(ifname)) end def new_interface(name) Puppet::Util::NetworkDevice::Cisco::Interface.new(canonalize_ifname(name), transport) end def parse_interface(name) resource = {} out = transport.command("sh interface #{name}") lines = out.split("\n") lines.shift; lines.pop lines.each do |l| if l =~ /#{name} is (.+), line protocol is / resource[:ensure] = ($1 == 'up' ? :present : :absent); end if l =~ /Auto Speed \(.+\),/ or l =~ /Auto Speed ,/ or l =~ /Auto-speed/ resource[:speed] = :auto end if l =~ /, (.+)Mb\/s/ resource[:speed] = $1 end if l =~ /\s+Auto-duplex \((.{4})\),/ resource[:duplex] = :auto end if l =~ /\s+(.+)-duplex/ resource[:duplex] = $1 == "Auto" ? :auto : $1.downcase.to_sym end if l =~ /Description: (.+)/ resource[:description] = $1 end end resource end def parse_interface_config(name) resource = Hash.new { |hash, key| hash[key] = Array.new ; } out = transport.command("sh running-config interface #{name} | begin interface") lines = out.split("\n") lines.shift; lines.pop lines.each do |l| if l =~ /ip address (#{IP}) (#{IP})\s+secondary\s*$/ resource[:ipaddress] << [prefix_length(IPAddr.new($2)), IPAddr.new($1), 'secondary'] end if l =~ /ip address (#{IP}) (#{IP})\s*$/ resource[:ipaddress] << [prefix_length(IPAddr.new($2)), IPAddr.new($1), nil] end if l =~ /ipv6 address (#{IP})\/(\d+) (eui-64|link-local)/ resource[:ipaddress] << [$2.to_i, IPAddr.new($1), $3] end if l =~ /channel-group\s+(\d+)/ resource[:etherchannel] = $1 end end resource end def parse_vlans vlans = {} out = transport.command(support_vlan_brief? ? "sh vlan brief" : "sh vlan-switch brief") lines = out.split("\n") lines.shift; lines.shift; lines.shift; lines.pop vlan = nil lines.each do |l| case l # vlan name status when /^(\d+)\s+(\w+)\s+(\w+)\s+([a-zA-Z0-9,\/. ]+)\s*$/ vlan = { :name => $1, :description => $2, :status => $3, :interfaces => [] } if $4.strip.length > 0 vlan[:interfaces] = $4.strip.split(/\s*,\s*/).map{ |ifn| canonalize_ifname(ifn) } end vlans[vlan[:name]] = vlan when /^\s+([a-zA-Z0-9,\/. ]+)\s*$/ raise "invalid sh vlan summary output" unless vlan if $1.strip.length > 0 vlan[:interfaces] += $1.strip.split(/\s*,\s*/).map{ |ifn| canonalize_ifname(ifn) } end else end end vlans end def update_vlan(id, is = {}, should = {}) if should[:ensure] == :absent Puppet.info "Removing #{id} from device vlan" transport.command("conf t") transport.command("no vlan #{id}") transport.command("exit") return end # We're creating or updating an entry transport.command("conf t") transport.command("vlan #{id}") [is.keys, should.keys].flatten.uniq.each do |property| Puppet.debug("trying property: #{property}: #{should[property]}") next if property != :description transport.command("name #{should[property]}") end transport.command("exit") transport.command("exit") end def parse_trunking(interface) trunking = {} out = transport.command("sh interface #{interface} switchport") lines = out.split("\n") lines.shift; lines.pop lines.each do |l| case l when /^Administrative mode:\s+(.*)$/i case $1 when "trunk" trunking[:mode] = :trunk when "static access" trunking[:mode] = :access else raise "Unknown switchport mode: #{$1} for #{interface}" end when /^Administrative Trunking Encapsulation:\s+(.*)$/ case $1 when "dot1q","isl" trunking[:encapsulation] = $1.to_sym if trunking[:mode] == :trunk else raise "Unknown switchport encapsulation: #{$1} for #{interface}" end when /^Access Mode VLAN:\s+(.*) \(\(Inactive\)\)$/ # nothing when /^Access Mode VLAN:\s+(.*) \(.*\)$/ trunking[:native_vlan] = $1 if trunking[:mode] == :access when /^Trunking VLANs Enabled:\s+(.*)$/ next if trunking[:mode] == :access vlans = $1 trunking[:allowed_trunk_vlans] = case vlans when /all/i :all when /none/i :none else vlans end end end trunking end end diff --git a/lib/puppet/util/rdoc.rb b/lib/puppet/util/rdoc.rb index c00bc6f85..fe1a3c5c3 100644 --- a/lib/puppet/util/rdoc.rb +++ b/lib/puppet/util/rdoc.rb @@ -1,86 +1,90 @@ - +require 'puppet/util' module Puppet::Util::RDoc - module_function # launch a rdoc documenation process # with the files/dir passed in +files+ def rdoc(outputdir, files, charset = nil) + unless Puppet.features.rdoc1? + raise "the version of RDoc included in Ruby #{::RUBY_VERSION} is not supported" + end + + begin Puppet[:ignoreimport] = true # then rdoc require 'rdoc/rdoc' require 'rdoc/options' # load our parser require 'puppet/util/rdoc/parser' r = RDoc::RDoc.new RDoc::RDoc::GENERATORS["puppet"] = RDoc::RDoc::Generator.new( - "puppet/util/rdoc/generators/puppet_generator.rb", - "PuppetGenerator".intern, - "puppet") + "puppet/util/rdoc/generators/puppet_generator.rb", + :PuppetGenerator, + "puppet" + ) # specify our own format & where to output options = [ "--fmt", "puppet", - "--quiet", - "--exclude", "/modules/[^/]*/files/.*\.pp$", - "--op", outputdir ] + "--quiet", + "--exclude", "/modules/[^/]*/files/.*\.pp$", + "--op", outputdir ] options << "--force-update" if Options::OptionList.options.any? { |o| o[0] == "--force-update" } options += [ "--charset", charset] if charset options += files - #TODO dedup file paths (not strict duplication sense, parents, children, etc # launch the documentation process r.document(options) - rescue RDoc::RDocError => e + rescue RDoc::RDocError => e raise Puppet::ParseError.new("RDoc error #{e}") + end end # launch a output to console manifest doc def manifestdoc(files) Puppet[:ignoreimport] = true files.select { |f| FileTest.file?(f) }.each do |f| parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new(Puppet[:environment])) parser.file = f ast = parser.parse output(f, ast) end end # Ouputs to the console the documentation # of a manifest def output(file, ast) astobj = [] ast.instantiate('').each do |resource_type| astobj << resource_type if resource_type.file == file end astobj.sort! {|a,b| a.line <=> b.line }.each do |k| output_astnode_doc(k) end end def output_astnode_doc(ast) puts ast.doc if !ast.doc.nil? and !ast.doc.empty? if Puppet.settings[:document_all] # scan each underlying resources to produce documentation code = ast.code.children if ast.code.is_a?(Puppet::Parser::AST::ASTArray) code ||= ast.code output_resource_doc(code) unless code.nil? end end def output_resource_doc(code) code.sort { |a,b| a.line <=> b.line }.each do |stmt| output_resource_doc(stmt.children) if stmt.is_a?(Puppet::Parser::AST::ASTArray) if stmt.is_a?(Puppet::Parser::AST::Resource) puts stmt.doc if !stmt.doc.nil? and !stmt.doc.empty? end end end - end diff --git a/lib/puppet/util/storage.rb b/lib/puppet/util/storage.rb index abc0bbcde..ed67b1d3d 100644 --- a/lib/puppet/util/storage.rb +++ b/lib/puppet/util/storage.rb @@ -1,96 +1,91 @@ require 'yaml' require 'sync' -require 'puppet/util/file_locking' - # a class for storing state class Puppet::Util::Storage include Singleton include Puppet::Util def self.state @@state end def initialize self.class.load end # Return a hash that will be stored to disk. It's worth noting # here that we use the object's full path, not just the name/type # combination. At the least, this is useful for those non-isomorphic # types like exec, but it also means that if an object changes locations # in the configuration it will lose its cache. def self.cache(object) if object.is_a?(Symbol) name = object else name = object.to_s end @@state[name] ||= {} end def self.clear @@state.clear Storage.init end def self.init @@state = {} @@splitchar = "\t" end self.init def self.load Puppet.settings.use(:main) unless FileTest.directory?(Puppet[:statedir]) + filename = Puppet[:statefile] - unless File.exists?(Puppet[:statefile]) + unless File.exists?(filename) self.init unless !@@state.nil? return end - unless File.file?(Puppet[:statefile]) - Puppet.warning("Checksumfile #{Puppet[:statefile]} is not a file, ignoring") + unless File.file?(filename) + Puppet.warning("Checksumfile #{filename} is not a file, ignoring") return end Puppet::Util.benchmark(:debug, "Loaded state") do - Puppet::Util::FileLocking.readlock(Puppet[:statefile]) do |file| + begin + @@state = YAML.load(::File.read(filename)) + rescue => detail + Puppet.err "Checksumfile #{filename} is corrupt (#{detail}); replacing" + begin - @@state = YAML.load(file) - rescue => detail - Puppet.err "Checksumfile #{Puppet[:statefile]} is corrupt (#{detail}); replacing" - begin - File.rename(Puppet[:statefile], Puppet[:statefile] + ".bad") - rescue - raise Puppet::Error, - "Could not rename corrupt #{Puppet[:statefile]}; remove manually" - end + File.rename(filename, filename + ".bad") + rescue + raise Puppet::Error, "Could not rename corrupt #{filename}; remove manually" end end end unless @@state.is_a?(Hash) Puppet.err "State got corrupted" self.init end - - #Puppet.debug "Loaded state is #{@@state.inspect}" end def self.stateinspect @@state.inspect end def self.store Puppet.debug "Storing state" Puppet.info "Creating state file #{Puppet[:statefile]}" unless FileTest.exist?(Puppet[:statefile]) Puppet::Util.benchmark(:debug, "Stored state") do - Puppet::Util::FileLocking.writelock(Puppet[:statefile], 0660) do |file| - file.print YAML.dump(@@state) + Puppet::Util.replace_file(Puppet[:statefile], 0660) do |fh| + fh.print YAML.dump(@@state) end end end end diff --git a/lib/puppet/util/tagging.rb b/lib/puppet/util/tagging.rb index 6323ee08c..b0f5e3258 100644 --- a/lib/puppet/util/tagging.rb +++ b/lib/puppet/util/tagging.rb @@ -1,56 +1,56 @@ # Created on 2008-01-19 # Copyright Luke Kanies # A common module to handle tagging. module Puppet::Util::Tagging # Add a tag to our current list. These tags will be added to all # of the objects contained in this scope. def tag(*ary) @tags ||= [] qualified = [] ary.collect { |tag| tag.to_s.downcase }.each do |tag| fail(Puppet::ParseError, "Invalid tag #{tag.inspect}") unless valid_tag?(tag) qualified << tag if tag.include?("::") @tags << tag unless @tags.include?(tag) end handle_qualified_tags( qualified ) end # Are we tagged with the provided tag? def tagged?(*tags) not ( self.tags & tags.flatten.collect { |t| t.to_s } ).empty? end # Return a copy of the tag list, so someone can't ask for our tags # and then modify them. def tags @tags ||= [] @tags.dup end def tags=(tags) @tags = [] return if tags.nil? or tags == "" tags = tags.strip.split(/\s*,\s*/) if tags.is_a?(String) tags.each do |t| tag(t) end end private def handle_qualified_tags( qualified ) # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com] qualified.collect { |name| x = name.split("::") }.flatten.each { |tag| @tags << tag unless @tags.include?(tag) } end def valid_tag?(tag) - tag =~ /^\w[-\w:.]*$/ + tag.is_a?(String) and tag =~ /^\w[-\w:.]*$/ end end diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb index e07a2d7b9..1d72c7e09 100644 --- a/lib/puppet/util/zaml.rb +++ b/lib/puppet/util/zaml.rb @@ -1,355 +1,360 @@ # encoding: UTF-8 # # The above encoding line is a magic comment to set the default source encoding # of this file for the Ruby interpreter. It must be on the first or second # line of the file if an interpreter is in use. In Ruby 1.9 and later, the # source encoding determines the encoding of String and Regexp objects created # from this source file. This explicit encoding is important becuase otherwise # Ruby will pick an encoding based on LANG or LC_CTYPE environment variables. # These may be different from site to site so it's important for us to # establish a consistent behavior. For more information on M17n please see: # http://links.puppetlabs.com/understanding_m17n # ZAML -- A partial replacement for YAML, writen with speed and code clarity # in mind. ZAML fixes one YAML bug (loading Exceptions) and provides # a replacement for YAML.dump unimaginatively called ZAML.dump, # which is faster on all known cases and an order of magnitude faster # with complex structures. # # http://github.com/hallettj/zaml # # Authors: Markus Roberts, Jesse Hallett, Ian McIntosh, Igal Koshevoy, Simon Chiang # require 'yaml' class ZAML VERSION = "0.1.1" # # Class Methods # def self.dump(stuff, where='') z = new stuff.to_zaml(z) where << z.to_s end # # Instance Methods # def initialize @result = [] @indent = nil @structured_key_prefix = nil @previously_emitted_object = {} @next_free_label_number = 0 emit('--- ') end def nested(tail=' ') old_indent = @indent @indent = "#{@indent || "\n"}#{tail}" yield @indent = old_indent end class Label # # YAML only wants objects in the datastream once; if the same object # occurs more than once, we need to emit a label ("&idxxx") on the # first occurrence and then emit a back reference (*idxxx") on any # subsequent occurrence(s). # # To accomplish this we keeps a hash (by object id) of the labels of # the things we serialize as we begin to serialize them. The labels # initially serialize as an empty string (since most objects are only # going to be be encountered once), but can be changed to a valid # (by assigning it a number) the first time it is subsequently used, # if it ever is. Note that we need to do the label setup BEFORE we # start to serialize the object so that circular structures (in # which we will encounter a reference to the object as we serialize # it can be handled). # attr_accessor :this_label_number def initialize(obj,indent) @indent = indent @this_label_number = nil @obj = obj # prevent garbage collection so that object id isn't reused end def to_s @this_label_number ? ('&id%03d%s' % [@this_label_number, @indent]) : '' end def reference @reference ||= '*id%03d' % @this_label_number end end def label_for(obj) @previously_emitted_object[obj.object_id] end def new_label_for(obj) label = Label.new(obj,(Hash === obj || Array === obj) ? "#{@indent || "\n"} " : ' ') @previously_emitted_object[obj.object_id] = label label end def first_time_only(obj) if label = label_for(obj) label.this_label_number ||= (@next_free_label_number += 1) emit(label.reference) else if @structured_key_prefix and not obj.is_a? String emit(@structured_key_prefix) @structured_key_prefix = nil end emit(new_label_for(obj)) yield end end def emit(s) @result << s @recent_nl = false unless s.kind_of?(Label) end def nl(s='') emit(@indent || "\n") unless @recent_nl emit(s) @recent_nl = true end def to_s @result.join end def prefix_structured_keys(x) @structured_key_prefix = x yield nl unless @structured_key_prefix @structured_key_prefix = nil end end ################################################################ # # Behavior for custom classes # ################################################################ class Object def to_yaml_properties instance_variables.sort # Default YAML behavior end def yaml_property_munge(x) x end def zamlized_class_name(root) cls = self.class "!ruby/#{root.name.downcase}#{cls == root ? '' : ":#{cls.respond_to?(:name) ? cls.name : cls}"}" end def to_zaml(z) z.first_time_only(self) { z.emit(zamlized_class_name(Object)) z.nested { instance_variables = to_yaml_properties if instance_variables.empty? z.emit(" {}") else instance_variables.each { |v| z.nl - v[1..-1].to_zaml(z) # Remove leading '@' + v.to_s[1..-1].to_zaml(z) # Remove leading '@' z.emit(': ') yaml_property_munge(instance_variable_get(v)).to_zaml(z) } end } } end end ################################################################ # # Behavior for built-in classes # ################################################################ class NilClass def to_zaml(z) z.emit('') # NOTE: blank turns into nil in YAML.load end end class Symbol def to_zaml(z) z.emit(self.inspect) end end class TrueClass def to_zaml(z) z.emit('true') end end class FalseClass def to_zaml(z) z.emit('false') end end class Numeric def to_zaml(z) z.emit(self) end end class Regexp def to_zaml(z) z.first_time_only(self) { z.emit("#{zamlized_class_name(Regexp)} #{inspect}") } end end class Exception def to_zaml(z) z.emit(zamlized_class_name(Exception)) z.nested { z.nl("message: ") message.to_zaml(z) } end # # Monkey patch for buggy Exception restore in YAML # # This makes it work for now but is not very future-proof; if things # change we'll most likely want to remove this. To mitigate the risks # as much as possible, we test for the bug before appling the patch. # if respond_to? :yaml_new and yaml_new(self, :tag, "message" => "blurp").message != "blurp" def self.yaml_new( klass, tag, val ) o = YAML.object_maker( klass, {} ).exception(val.delete( 'message')) val.each_pair do |k,v| o.instance_variable_set("@#{k}", v) end o end end end class String ZAML_ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a \x08 \t \n \v \f \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f } def escaped_for_zaml # JJM (Note the trailing dots to construct a multi-line method chain.) This # code is meant to escape all bytes which are not ASCII-8BIT printable # characters. Multi-byte unicode characters are handled just fine because # each byte of the character results in an escaped string emitted to the # YAML stream. When the YAML is de-serialized back into a String the bytes # will be reconstructed properly into the unicode character. self.to_ascii8bit.gsub( /\x5C/n, "\\\\\\" ). # Demi-kludge for Maglev/rubinius; the regexp should be /\\/ but parsetree chokes on that. gsub( /"/n, "\\\"" ). - gsub( /([\x00-\x1F])/n ) { |x| ZAML_ESCAPES[ x.unpack("C")[0] ] }. - gsub( /([\x80-\xFF])/n ) { |x| "\\x#{x.unpack("C")[0].to_s(16)}" } + gsub( /([\x00-\x1F])/n ) { |x| ZAML_ESCAPES[ x.unpack("C")[0] ] } end def to_zaml(z) z.first_time_only(self) { num = '[-+]?(0x)?\d+\.?\d*' case - when self == '' - z.emit('""') - # when self =~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/ - # z.emit("!binary |\n") - # z.emit([self].pack("m*")) - when ( - (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or - (self =~ /\A\n* /) or - (self =~ /[\s:]$/) or - (self =~ /^[>|][-+\d]*\s/i) or - (self[-1..-1] =~ /\s/) or - # This regular expression assumes the string is a byte sequence. - # It does not concern itself with characters so we convert the string - # to ASCII-8BIT for Ruby 1.9 to match up encodings. - (self.to_ascii8bit=~ /[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/n) or - (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or - (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/) - ) - z.emit("\"#{escaped_for_zaml}\"") - when self =~ /\n/ - if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end - z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } - else - z.emit(self) + when self == '' + z.emit('""') + when self.to_ascii8bit !~ /\A(?: # ?: non-capturing group (grouping with no back references) + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*\z/mnx + + z.emit("!binary ") + z.emit([self].pack("m*")) + when ( + (self =~ /\A(true|false|yes|no|on|null|off|#{num}(:#{num})*|!|=|~)$/i) or + (self =~ /\A\n* /) or + (self =~ /[\s:]$/) or + (self =~ /^[>|][-+\d]*\s/i) or + (self[-1..-1] =~ /\s/) or + (self =~ /[,\[\]\{\}\r\t]|:\s|\s#/) or + (self =~ /\A([-:?!#&*'"]|<<|%.+:.)/) + ) + z.emit("\"#{escaped_for_zaml}\"") + when self =~ /\n/ + if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end + z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } + else + z.emit(self) end } end # Return a guranteed ASCII-8BIT encoding for Ruby 1.9 This is a helper # method for other methods that perform regular expressions against byte # sequences deliberately rather than dealing with characters. # The method may or may not return a new instance. def to_ascii8bit if self.respond_to?(:encoding) and self.encoding.name != "ASCII-8BIT" then str = self.dup str.force_encoding("ASCII-8BIT") return str else return self end end end class Hash def to_zaml(z) z.first_time_only(self) { z.nested { if empty? z.emit('{}') else each_pair { |k, v| z.nl z.prefix_structured_keys('? ') { k.to_zaml(z) } z.emit(': ') v.to_zaml(z) } end } } end end class Array def to_zaml(z) z.first_time_only(self) { z.nested { if empty? z.emit('[]') else each { |v| z.nl('- '); v.to_zaml(z) } end } } end end class Time def to_zaml(z) # 2008-12-06 10:06:51.373758 -07:00 ms = ("%0.6f" % (usec * 1e-6)).sub(/^\d+\./,'') offset = "%+0.2i:%0.2i" % [utc_offset / 3600, (utc_offset / 60) % 60] z.emit(self.strftime("%Y-%m-%d %H:%M:%S.#{ms} #{offset}")) end end class Date def to_zaml(z) z.emit(strftime('%Y-%m-%d')) end end class Range def to_zaml(z) z.first_time_only(self) { z.emit(zamlized_class_name(Range)) z.nested { z.nl z.emit('begin: ') z.emit(first) z.nl z.emit('end: ') z.emit(last) z.nl z.emit('excl: ') z.emit(exclude_end?) } } end end diff --git a/test/data/providers/cron/crontab_sample_records.yaml b/spec/fixtures/unit/provider/cron/crontab/single_line.yaml similarity index 100% rename from test/data/providers/cron/crontab_sample_records.yaml rename to spec/fixtures/unit/provider/cron/crontab/single_line.yaml diff --git a/test/data/types/sshkey/1 b/spec/fixtures/unit/provider/sshkey/parsed/sample similarity index 100% rename from test/data/types/sshkey/1 rename to spec/fixtures/unit/provider/sshkey/parsed/sample diff --git a/spec/integration/application/doc_spec.rb b/spec/integration/application/doc_spec.rb index 0a323e0af..98e8392a4 100755 --- a/spec/integration/application/doc_spec.rb +++ b/spec/integration/application/doc_spec.rb @@ -1,55 +1,55 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet_spec/files' require 'puppet/application/doc' describe Puppet::Application::Doc do include PuppetSpec::Files - it "should not generate an error when module dir overlaps parent of site.pp (#4798)", :'fails_on_ruby_1.9.2' => true, :unless => Puppet.features.microsoft_windows? do + it "should not generate an error when module dir overlaps parent of site.pp (#4798)", :if => Puppet.features.rdoc1?, :unless => Puppet.features.microsoft_windows? do begin # Note: the directory structure below is more complex than it # needs to be, but it's representative of the directory structure # used in bug #4798. old_dir = Dir.getwd # Note: can't use chdir with a block because it will generate bogus warnings tmpdir = tmpfile('doc_spec') Dir.mkdir(tmpdir) Dir.chdir(tmpdir) site_file = 'site.pp' File.open(site_file, 'w') do |f| f.puts '# A comment' end modules_dir = 'modules' Dir.mkdir(modules_dir) rt_dir = File.join(modules_dir, 'rt') Dir.mkdir(rt_dir) manifests_dir = File.join(rt_dir, 'manifests') Dir.mkdir(manifests_dir) rt_file = File.join(manifests_dir, 'rt.pp') File.open(rt_file, 'w') do |f| f.puts '# A class' f.puts 'class foo { }' f.puts '# A definition' f.puts 'define bar { }' end puppet = Puppet::Application[:doc] Puppet[:modulepath] = modules_dir Puppet[:manifest] = site_file puppet.options[:mode] = :rdoc expect { puppet.run_command }.to exit_with 0 File.should be_exist('doc') ensure Dir.chdir(old_dir) end end it "should respect the -o option" do puppetdoc = Puppet::Application[:doc] puppetdoc.command_line.stubs(:args).returns(['foo', '-o', 'bar']) puppetdoc.parse_options puppetdoc.options[:outputdir].should == 'bar' end end diff --git a/spec/integration/defaults_spec.rb b/spec/integration/defaults_spec.rb index 2dd290f5c..27fefe863 100755 --- a/spec/integration/defaults_spec.rb +++ b/spec/integration/defaults_spec.rb @@ -1,315 +1,313 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/defaults' require 'puppet/rails' describe "Puppet defaults" do - after { Puppet.settings.clear } - describe "when setting the :factpath" do it "should add the :factpath to Facter's search paths" do Facter.expects(:search).with("/my/fact/path") Puppet.settings[:factpath] = "/my/fact/path" end end describe "when setting the :certname" do it "should fail if the certname is not downcased" do lambda { Puppet.settings[:certname] = "Host.Domain.Com" }.should raise_error(ArgumentError) end end describe "when setting :node_name_value" do it "should default to the value of :certname" do Puppet.settings[:certname] = 'blargle' Puppet.settings[:node_name_value].should == 'blargle' end end describe "when setting the :node_name_fact" do it "should fail when also setting :node_name_value" do lambda do Puppet.settings[:node_name_value] = "some value" Puppet.settings[:node_name_fact] = "some_fact" end.should raise_error("Cannot specify both the node_name_value and node_name_fact settings") end it "should not fail when using the default for :node_name_value" do lambda do Puppet.settings[:node_name_fact] = "some_fact" end.should_not raise_error end end describe "when :certdnsnames is set" do it "should not fail" do expect { Puppet[:certdnsnames] = 'fred:wilma' }.should_not raise_error end it "should warn the value is ignored" do Puppet.expects(:warning).with {|msg| msg =~ /CVE-2011-3872/ } Puppet[:certdnsnames] = 'fred:wilma' end end describe "when configuring the :crl" do it "should warn if :cacrl is set to false" do Puppet.expects(:warning) Puppet.settings[:cacrl] = 'false' end end describe "when setting the :catalog_format" do it "should log a deprecation notice" do Puppet.expects(:deprecation_warning) Puppet.settings[:catalog_format] = 'marshal' end it "should copy the value to :preferred_serialization_format" do Puppet.settings[:catalog_format] = 'marshal' Puppet.settings[:preferred_serialization_format].should == 'marshal' end end it "should have a clientyamldir setting" do Puppet.settings[:clientyamldir].should_not be_nil end it "should have different values for the yamldir and clientyamldir" do Puppet.settings[:yamldir].should_not == Puppet.settings[:clientyamldir] end it "should have a client_datadir setting" do Puppet.settings[:client_datadir].should_not be_nil end it "should have different values for the server_datadir and client_datadir" do Puppet.settings[:server_datadir].should_not == Puppet.settings[:client_datadir] end # See #1232 it "should not specify a user or group for the clientyamldir" do Puppet.settings.setting(:clientyamldir).owner.should be_nil Puppet.settings.setting(:clientyamldir).group.should be_nil end it "should use the service user and group for the yamldir" do Puppet.settings.stubs(:service_user_available?).returns true Puppet.settings.setting(:yamldir).owner.should == Puppet.settings[:user] Puppet.settings.setting(:yamldir).group.should == Puppet.settings[:group] end # See #1232 it "should not specify a user or group for the rundir" do Puppet.settings.setting(:rundir).owner.should be_nil Puppet.settings.setting(:rundir).group.should be_nil end it "should specify that the host private key should be owned by the service user" do Puppet.settings.stubs(:service_user_available?).returns true Puppet.settings.setting(:hostprivkey).owner.should == Puppet.settings[:user] end it "should specify that the host certificate should be owned by the service user" do Puppet.settings.stubs(:service_user_available?).returns true Puppet.settings.setting(:hostcert).owner.should == Puppet.settings[:user] end it "should use a bind address of ''" do Puppet.settings.clear Puppet.settings[:bindaddress].should == "" end [:modulepath, :factpath].each do |setting| it "should configure '#{setting}' not to be a file setting, so multi-directory settings are acceptable" do Puppet.settings.setting(setting).should be_instance_of(Puppet::Util::Settings::StringSetting) end end it "should add /usr/sbin and /sbin to the path if they're not there" do Puppet::Util.withenv("PATH" => "/usr/bin:/usr/local/bin") do Puppet.settings[:path] = "none" # this causes it to ignore the setting ENV["PATH"].split(File::PATH_SEPARATOR).should be_include("/usr/sbin") ENV["PATH"].split(File::PATH_SEPARATOR).should be_include("/sbin") end end it "should default to pson for the preferred serialization format" do Puppet.settings.value(:preferred_serialization_format).should == "pson" end describe "when enabling storeconfigs" do before do Puppet::Resource::Catalog.indirection.stubs(:cache_class=) Puppet::Node::Facts.indirection.stubs(:cache_class=) Puppet::Node.indirection.stubs(:cache_class=) Puppet.features.stubs(:rails?).returns true end it "should set the Catalog cache class to :store_configs" do Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:store_configs) Puppet.settings[:storeconfigs] = true end it "should not set the Catalog cache class to :store_configs if asynchronous storeconfigs is enabled" do Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:store_configs).never Puppet.settings.expects(:value).with(:async_storeconfigs).returns true Puppet.settings[:storeconfigs] = true end it "should set the Facts cache class to :store_configs" do Puppet::Node::Facts.indirection.expects(:cache_class=).with(:store_configs) Puppet.settings[:storeconfigs] = true end it "should set the Node cache class to :store_configs" do Puppet::Node.indirection.expects(:cache_class=).with(:store_configs) Puppet.settings[:storeconfigs] = true end end describe "when enabling asynchronous storeconfigs" do before do Puppet::Resource::Catalog.indirection.stubs(:cache_class=) Puppet::Node::Facts.indirection.stubs(:cache_class=) Puppet::Node.indirection.stubs(:cache_class=) Puppet.features.stubs(:rails?).returns true end it "should set storeconfigs to true" do Puppet.settings[:async_storeconfigs] = true Puppet.settings[:storeconfigs].should be_true end it "should set the Catalog cache class to :queue" do Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:queue) Puppet.settings[:async_storeconfigs] = true end it "should set the Facts cache class to :store_configs" do Puppet::Node::Facts.indirection.expects(:cache_class=).with(:store_configs) Puppet.settings[:storeconfigs] = true end it "should set the Node cache class to :store_configs" do Puppet::Node.indirection.expects(:cache_class=).with(:store_configs) Puppet.settings[:storeconfigs] = true end end describe "when enabling thin storeconfigs" do before do Puppet::Resource::Catalog.indirection.stubs(:cache_class=) Puppet::Node::Facts.indirection.stubs(:cache_class=) Puppet::Node.indirection.stubs(:cache_class=) Puppet.features.stubs(:rails?).returns true end it "should set storeconfigs to true" do Puppet.settings[:thin_storeconfigs] = true Puppet.settings[:storeconfigs].should be_true end end it "should have a setting for determining the configuration version and should default to an empty string" do Puppet.settings[:config_version].should == "" end describe "when enabling reports" do it "should use the default server value when report server is unspecified" do Puppet.settings[:server] = "server" Puppet.settings[:report_server].should == "server" end it "should use the default masterport value when report port is unspecified" do Puppet.settings[:masterport] = "1234" Puppet.settings[:report_port].should == "1234" end it "should set report_server when reportserver is set" do Puppet.settings[:reportserver] = "reportserver" Puppet.settings[:report_server].should == "reportserver" end it "should use report_port when set" do Puppet.settings[:masterport] = "1234" Puppet.settings[:report_port] = "5678" Puppet.settings[:report_port].should == "5678" end it "should prefer report_server over reportserver" do Puppet.settings[:reportserver] = "reportserver" Puppet.settings[:report_server] = "report_server" Puppet.settings[:report_server].should == "report_server" end end it "should have a :caname setting that defaults to the cert name" do Puppet.settings[:certname] = "foo" Puppet.settings[:ca_name].should == "Puppet CA: foo" end it "should have a 'prerun_command' that defaults to the empty string" do Puppet.settings[:prerun_command].should == "" end it "should have a 'postrun_command' that defaults to the empty string" do Puppet.settings[:postrun_command].should == "" end it "should have a 'certificate_revocation' setting that defaults to true" do Puppet.settings[:certificate_revocation].should be_true end it "should have an http_compression setting that defaults to false" do Puppet.settings[:http_compression].should be_false end describe "reportdir" do subject { Puppet.settings[:reportdir] } it { should == "#{Puppet[:vardir]}/reports" } end describe "reporturl" do subject { Puppet.settings[:reporturl] } it { should == "http://localhost:3000/reports/upload" } end describe "when configuring color" do it "should default to ansi", :unless => Puppet.features.microsoft_windows? do Puppet.settings[:color].should == 'ansi' end it "should default to false", :if => Puppet.features.microsoft_windows? do Puppet.settings[:color].should == 'false' end end describe "daemonize" do it "should default to true", :unless => Puppet.features.microsoft_windows? do Puppet.settings[:daemonize].should == true end describe "on Windows", :if => Puppet.features.microsoft_windows? do it "should default to false" do Puppet.settings[:daemonize].should == false end it "should raise an error if set to true" do lambda { Puppet.settings[:daemonize] = true }.should raise_error(/Cannot daemonize on Windows/) end end end describe "diff" do it "should default to 'diff' on POSIX", :unless => Puppet.features.microsoft_windows? do Puppet.settings[:diff].should == 'diff' end it "should default to '' on Windows", :if => Puppet.features.microsoft_windows? do Puppet.settings[:diff].should == '' end end end diff --git a/spec/integration/network/formats_spec.rb b/spec/integration/network/formats_spec.rb index f6e234de3..faf667439 100755 --- a/spec/integration/network/formats_spec.rb +++ b/spec/integration/network/formats_spec.rb @@ -1,104 +1,104 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/network/formats' class PsonIntTest attr_accessor :string def ==(other) other.class == self.class and string == other.string end def self.from_pson(data) new(data[0]) end def initialize(string) @string = string end def to_pson(*args) { 'type' => self.class.name, 'data' => [@string] }.to_pson(*args) end def self.canonical_order(s) s.gsub(/\{"data":\[(.*?)\],"type":"PsonIntTest"\}/,'{"type":"PsonIntTest","data":[\1]}') end end describe Puppet::Network::FormatHandler.format(:s) do before do @format = Puppet::Network::FormatHandler.format(:s) end it "should support certificates" do @format.should be_supported(Puppet::SSL::Certificate) end it "should not support catalogs" do @format.should_not be_supported(Puppet::Resource::Catalog) end end -describe Puppet::Network::FormatHandler.format(:pson), :'fails_on_ruby_1.9.2' => true do +describe Puppet::Network::FormatHandler.format(:pson) do describe "when pson is absent", :if => (! Puppet.features.pson?) do before do @pson = Puppet::Network::FormatHandler.format(:pson) end it "should not be suitable" do @pson.should_not be_suitable end end describe "when pson is available", :if => Puppet.features.pson? do before do @pson = Puppet::Network::FormatHandler.format(:pson) end it "should be able to render an instance to pson" do instance = PsonIntTest.new("foo") PsonIntTest.canonical_order(@pson.render(instance)).should == PsonIntTest.canonical_order('{"type":"PsonIntTest","data":["foo"]}' ) end it "should be able to render arrays to pson" do @pson.render([1,2]).should == '[1,2]' end it "should be able to render arrays containing hashes to pson" do @pson.render([{"one"=>1},{"two"=>2}]).should == '[{"one":1},{"two":2}]' end it "should be able to render multiple instances to pson" do one = PsonIntTest.new("one") two = PsonIntTest.new("two") PsonIntTest.canonical_order(@pson.render([one,two])).should == PsonIntTest.canonical_order('[{"type":"PsonIntTest","data":["one"]},{"type":"PsonIntTest","data":["two"]}]') end it "should be able to intern pson into an instance" do @pson.intern(PsonIntTest, '{"type":"PsonIntTest","data":["foo"]}').should == PsonIntTest.new("foo") end it "should be able to intern pson with no class information into an instance" do @pson.intern(PsonIntTest, '["foo"]').should == PsonIntTest.new("foo") end it "should be able to intern multiple instances from pson" do @pson.intern_multiple(PsonIntTest, '[{"type": "PsonIntTest", "data": ["one"]},{"type": "PsonIntTest", "data": ["two"]}]').should == [ PsonIntTest.new("one"), PsonIntTest.new("two") ] end it "should be able to intern multiple instances from pson with no class information" do @pson.intern_multiple(PsonIntTest, '[["one"],["two"]]').should == [ PsonIntTest.new("one"), PsonIntTest.new("two") ] end end end diff --git a/spec/integration/network/server/mongrel_spec.rb b/spec/integration/network/server/mongrel_spec.rb index 1ce59eb49..aef708dc5 100755 --- a/spec/integration/network/server/mongrel_spec.rb +++ b/spec/integration/network/server/mongrel_spec.rb @@ -1,64 +1,70 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/network/server' -require 'socket' +require 'net/http' -describe Puppet::Network::Server, :'fails_on_ruby_1.9.2' => true do +describe Puppet::Network::Server do describe "when using mongrel", :if => Puppet.features.mongrel? do + # This reduces the odds of conflicting port numbers between concurrent runs + # of the suite on the same machine dramatically. + def port + 20001 + ($$ % 40000) + end + before :each do Puppet[:servertype] = 'mongrel' Puppet[:server] = '127.0.0.1' - @params = { :port => 34346, :handlers => [ :node ] } + @params = { :port => port, :handlers => [ :node ] } @server = Puppet::Network::Server.new(@params) end - after { Puppet.settings.clear } + after :each do + @server.unlisten if @server.listening? + end describe "before listening" do it "should not be reachable at the specified address and port" do - lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED) + lambda { Net::HTTP.get('127.0.0.1', '/', port) }. + should raise_error(Errno::ECONNREFUSED) end end describe "when listening" do it "should be reachable on the specified address and port" do @server.listen - lambda { TCPSocket.new('127.0.0.1', 34346) }.should_not raise_error + expect { Net::HTTP.get('127.0.0.1', '/', port) }.should_not raise_error end it "should default to '127.0.0.1' as its bind address" do @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening @server.send(:http_server).expects(:listen).with { |args| args[:address] == "127.0.0.1" } @server.listen end it "should use any specified bind address" do Puppet[:bindaddress] = "0.0.0.0" @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening @server.send(:http_server).expects(:listen).with { |args| args[:address] == "0.0.0.0" } @server.listen end it "should not allow multiple servers to listen on the same address and port" do @server.listen @server2 = Puppet::Network::Server.new(@params) lambda { @server2.listen }.should raise_error end end describe "after unlistening" do it "should not be reachable on the port and address assigned" do @server.listen @server.unlisten - lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED) + expect { Net::HTTP.get('127.0.0.1', '/', port) }. + should raise_error Errno::ECONNREFUSED end end - - after :each do - @server.unlisten if @server.listening? - end end end diff --git a/spec/integration/network/server/webrick_spec.rb b/spec/integration/network/server/webrick_spec.rb index f50801e38..0f31855b2 100755 --- a/spec/integration/network/server/webrick_spec.rb +++ b/spec/integration/network/server/webrick_spec.rb @@ -1,84 +1,90 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/network/server' require 'puppet/ssl/certificate_authority' require 'socket' describe Puppet::Network::Server, :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files + # This reduces the odds of conflicting port numbers between concurrent runs + # of the suite on the same machine dramatically. + def port + 20000 + ($$ % 40000) + end + describe "when using webrick" do before :each do Puppet[:servertype] = 'webrick' Puppet[:server] = '127.0.0.1' - @params = { :port => 34343, :handlers => [ :node ] } + @params = { :port => port, :handlers => [ :node ] } # Get a safe temporary file dir = tmpdir("webrick_integration_testing") Puppet.settings[:confdir] = dir Puppet.settings[:vardir] = dir Puppet.settings[:logdir] = dir Puppet.settings[:group] = Process.gid Puppet::SSL::Host.ca_location = :local ca = Puppet::SSL::CertificateAuthority.new ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.indirection.find(Puppet[:certname]) end after do Puppet.settings.clear Puppet::SSL::Host.ca_location = :none end describe "before listening" do it "should not be reachable at the specified address and port" do - lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error + lambda { TCPSocket.new('127.0.0.1', port) }.should raise_error end end describe "when listening" do it "should be reachable on the specified address and port" do - @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server = Puppet::Network::Server.new(@params.merge(:port => port)) @server.listen - lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error + lambda { TCPSocket.new('127.0.0.1', port) }.should_not raise_error end it "should default to '0.0.0.0' as its bind address" do Puppet.settings.clear Puppet[:servertype] = 'webrick' Puppet[:bindaddress].should == '0.0.0.0' end it "should use any specified bind address" do Puppet[:bindaddress] = "127.0.0.1" - @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server = Puppet::Network::Server.new(@params.merge(:port => port)) @server.stubs(:unlisten) # we're breaking listening internally, so we have to keep it from unlistening @server.send(:http_server).expects(:listen).with { |args| args[:address] == "127.0.0.1" } @server.listen end it "should not allow multiple servers to listen on the same address and port" do - @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server = Puppet::Network::Server.new(@params.merge(:port => port)) @server.listen - @server2 = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server2 = Puppet::Network::Server.new(@params.merge(:port => port)) lambda { @server2.listen }.should raise_error end after :each do @server.unlisten if @server && @server.listening? end end describe "after unlistening" do it "should not be reachable on the port and address assigned" do - @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server = Puppet::Network::Server.new(@params.merge(:port => port)) @server.listen @server.unlisten - lambda { TCPSocket.new('127.0.0.1', 34343) }.should raise_error(Errno::ECONNREFUSED) + lambda { TCPSocket.new('127.0.0.1', port) }.should raise_error(Errno::ECONNREFUSED) end end end end diff --git a/spec/integration/node_spec.rb b/spec/integration/node_spec.rb index 5abb880a3..7efe524c4 100755 --- a/spec/integration/node_spec.rb +++ b/spec/integration/node_spec.rb @@ -1,92 +1,92 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/node' describe Puppet::Node do describe "when delegating indirection calls" do before do Puppet::Node.indirection.reset_terminus_class Puppet::Node.indirection.cache_class = nil @name = "me" @node = Puppet::Node.new(@name) end it "should be able to use the exec terminus" do Puppet::Node.indirection.stubs(:terminus_class).returns :exec # Load now so we can stub terminus = Puppet::Node.indirection.terminus(:exec) terminus.expects(:query).with(@name).returns "myresults" terminus.expects(:translate).with(@name, "myresults").returns "translated_results" terminus.expects(:create_node).with(@name, "translated_results").returns @node Puppet::Node.indirection.find(@name).should equal(@node) end it "should be able to use the yaml terminus" do Puppet::Node.indirection.stubs(:terminus_class).returns :yaml # Load now, before we stub the exists? method. terminus = Puppet::Node.indirection.terminus(:yaml) terminus.expects(:path).with(@name).returns "/my/yaml/file" FileTest.expects(:exist?).with("/my/yaml/file").returns false Puppet::Node.indirection.find(@name).should be_nil end it "should have an ldap terminus" do Puppet::Node.indirection.terminus(:ldap).should_not be_nil end - it "should be able to use the plain terminus", :'fails_on_ruby_1.9.2' => true do + it "should be able to use the plain terminus" do Puppet::Node.indirection.stubs(:terminus_class).returns :plain # Load now, before we stub the exists? method. Puppet::Node.indirection.terminus(:plain) Puppet::Node.expects(:new).with(@name).returns @node Puppet::Node.indirection.find(@name).should equal(@node) end describe "and using the memory terminus" do before do @name = "me" @old_terminus = Puppet::Node.indirection.terminus_class @terminus = Puppet::Node.indirection.terminus(:memory) Puppet::Node.indirection.stubs(:terminus).returns @terminus @node = Puppet::Node.new(@name) end it "should find no nodes by default" do Puppet::Node.indirection.find(@name).should be_nil end it "should be able to find nodes that were previously saved" do Puppet::Node.indirection.save(@node) Puppet::Node.indirection.find(@name).should equal(@node) end it "should replace existing saved nodes when a new node with the same name is saved" do Puppet::Node.indirection.save(@node) two = Puppet::Node.new(@name) Puppet::Node.indirection.save(two) Puppet::Node.indirection.find(@name).should equal(two) end it "should be able to remove previously saved nodes" do Puppet::Node.indirection.save(@node) Puppet::Node.indirection.destroy(@node.name) Puppet::Node.indirection.find(@name).should be_nil end it "should fail when asked to destroy a node that does not exist" do proc { Puppet::Node.indirection.destroy(@node) }.should raise_error(ArgumentError) end end end end diff --git a/spec/integration/provider/package_spec.rb b/spec/integration/provider/package_spec.rb index e0d628f4b..2c6a92d74 100755 --- a/spec/integration/provider/package_spec.rb +++ b/spec/integration/provider/package_spec.rb @@ -1,44 +1,44 @@ #!/usr/bin/env rspec require 'spec_helper' -describe "Package provider", :'fails_on_ruby_1.9.2' => true do +describe "Package provider" do include PuppetSpec::Files Puppet::Type.type(:package).providers.each do |name| provider = Puppet::Type.type(:package).provider(name) describe name, :if => provider.suitable? do it "should fail when asked to install an invalid package" do pending("This test hangs forever with recent versions of RubyGems") if provider.name == :gem options = {:name => "nosuch#{provider.name}", :provider => provider.name} # The MSI provider requires that source be specified as it is # what actually determines if the package exists. if provider.name == :msi options[:source] = tmpfile("msi_package") end pkg = Puppet::Type.newpackage(options) lambda { pkg.provider.install }.should raise_error end it "should be able to get a list of existing packages", :fails_on_windows => true do if provider.name == :msi Puppet[:vardir] = tmpdir('msi_package_var_dir') end # the instances method requires root priviledges on gentoo # if the eix cache is outdated (to run eix-update) so make # sure we dont actually run eix-update if provider.name == :portage provider.stubs(:update_eix).returns('Database contains 15240 packages in 155 categories') end provider.instances.each do |package| package.should be_instance_of(provider) package.properties[:provider].should == provider.name end end end end end diff --git a/spec/integration/provider/service/init_spec.rb b/spec/integration/provider/service/init_spec.rb index 483507d5f..b906b20ae 100755 --- a/spec/integration/provider/service/init_spec.rb +++ b/spec/integration/provider/service/init_spec.rb @@ -1,30 +1,30 @@ #!/usr/bin/env rspec require 'spec_helper' provider = Puppet::Type.type(:service).provider(:init) -describe provider, :'fails_on_ruby_1.9.2' => true do +describe provider do describe "when running on FreeBSD", :if => (Facter.value(:operatingsystem) == "FreeBSD") do it "should set its default path to include /etc/rc.d and /usr/local/etc/rc.d" do provider.defpath.should == ["/etc/rc.d", "/usr/local/etc/rc.d"] end end describe "when running on HP-UX", :if => (Facter.value(:operatingsystem) == "HP-UX") do it "should set its default path to include /sbin/init.d" do provider.defpath.should == "/sbin/init.d" end end describe "when running on Archlinux", :if => (Facter.value(:operatingsystem) == "Archlinux") do it "should set its default path to include /etc/rc.d" do provider.defpath.should == "/etc/rc.d" end end describe "when not running on FreeBSD, HP-UX or Archlinux", :if => (! %w{HP-UX FreeBSD Archlinux}.include?(Facter.value(:operatingsystem))) do it "should set its default path to include /etc/init.d" do provider.defpath.should == "/etc/init.d" end end end diff --git a/spec/integration/transaction_spec.rb b/spec/integration/transaction_spec.rb index f9b6c23e8..c5928a33a 100755 --- a/spec/integration/transaction_spec.rb +++ b/spec/integration/transaction_spec.rb @@ -1,346 +1,346 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/transaction' describe Puppet::Transaction do include PuppetSpec::Files before do Puppet::Util::Storage.stubs(:store) end def mk_catalog(*resources) catalog = Puppet::Resource::Catalog.new(Puppet::Node.new("mynode")) resources.each { |res| catalog.add_resource res } catalog end def usr_bin_touch(path) Puppet.features.microsoft_windows? ? "#{ENV['windir']}/system32/cmd.exe /c \"type NUL >> \"#{path}\"\"" : "/usr/bin/touch #{path}" end def touch(path) Puppet.features.microsoft_windows? ? "cmd.exe /c \"type NUL >> \"#{path}\"\"" : "touch #{path}" end it "should not apply generated resources if the parent resource fails" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar"), :backup => false catalog.add_resource resource child_resource = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar/baz"), :backup => false resource.expects(:eval_generate).returns([child_resource]) transaction = Puppet::Transaction.new(catalog) resource.expects(:retrieve).raises "this is a failure" resource.stubs(:err) child_resource.expects(:retrieve).never transaction.evaluate end it "should not apply virtual resources" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar"), :backup => false resource.virtual = true catalog.add_resource resource transaction = Puppet::Transaction.new(catalog) resource.expects(:evaluate).never transaction.evaluate end it "should apply exported resources" do catalog = Puppet::Resource::Catalog.new path = tmpfile("exported_files") resource = Puppet::Type.type(:file).new :path => path, :backup => false, :ensure => :file resource.exported = true catalog.add_resource resource catalog.apply FileTest.should be_exist(path) end it "should not apply virtual exported resources" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar"), :backup => false resource.exported = true resource.virtual = true catalog.add_resource resource transaction = Puppet::Transaction.new(catalog) resource.expects(:evaluate).never transaction.evaluate end it "should not apply device resources on normal host" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:interface).new :name => "FastEthernet 0/1" catalog.add_resource resource transaction = Puppet::Transaction.new(catalog) transaction.for_network_device = false transaction.expects(:apply).never.with(resource, nil) transaction.evaluate transaction.resource_status(resource).should be_skipped end it "should not apply host resources on device" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar"), :backup => false catalog.add_resource resource transaction = Puppet::Transaction.new(catalog) transaction.for_network_device = true transaction.expects(:apply).never.with(resource, nil) transaction.evaluate transaction.resource_status(resource).should be_skipped end it "should apply device resources on device" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:interface).new :name => "FastEthernet 0/1" catalog.add_resource resource transaction = Puppet::Transaction.new(catalog) transaction.for_network_device = true transaction.expects(:apply).with(resource, nil) transaction.evaluate transaction.resource_status(resource).should_not be_skipped end it "should apply resources appliable on host and device on a device" do catalog = Puppet::Resource::Catalog.new resource = Puppet::Type.type(:schedule).new :name => "test" catalog.add_resource resource transaction = Puppet::Transaction.new(catalog) transaction.for_network_device = true transaction.expects(:apply).with(resource, nil) transaction.evaluate transaction.resource_status(resource).should_not be_skipped end # Verify that one component requiring another causes the contained # resources in the requiring component to get refreshed. it "should propagate events from a contained resource through its container to its dependent container's contained resources" do transaction = nil file = Puppet::Type.type(:file).new :path => tmpfile("event_propagation"), :ensure => :present execfile = File.join(tmpdir("exec_event"), "exectestingness2") exec = Puppet::Type.type(:exec).new :command => touch(execfile), :path => ENV['PATH'] catalog = mk_catalog(file) fcomp = Puppet::Type.type(:component).new(:name => "Foo[file]") catalog.add_resource fcomp catalog.add_edge(fcomp, file) ecomp = Puppet::Type.type(:component).new(:name => "Foo[exec]") catalog.add_resource ecomp catalog.add_resource exec catalog.add_edge(ecomp, exec) ecomp[:subscribe] = Puppet::Resource.new(:foo, "file") exec[:refreshonly] = true exec.expects(:refresh) catalog.apply end # Make sure that multiple subscriptions get triggered. it "should propagate events to all dependent resources" do path = tmpfile("path") file1 = tmpfile("file1") file2 = tmpfile("file2") file = Puppet::Type.type(:file).new( :path => path, :ensure => "file" ) exec1 = Puppet::Type.type(:exec).new( :path => ENV["PATH"], :command => touch(file1), :refreshonly => true, :subscribe => Puppet::Resource.new(:file, path) ) exec2 = Puppet::Type.type(:exec).new( :path => ENV["PATH"], :command => touch(file2), :refreshonly => true, :subscribe => Puppet::Resource.new(:file, path) ) catalog = mk_catalog(file, exec1, exec2) catalog.apply FileTest.should be_exist(file1) FileTest.should be_exist(file2) end it "should not let one failed refresh result in other refreshes failing" do path = tmpfile("path") newfile = tmpfile("file") file = Puppet::Type.type(:file).new( :path => path, :ensure => "file" ) exec1 = Puppet::Type.type(:exec).new( :path => ENV["PATH"], :command => touch(File.expand_path("/this/cannot/possibly/exist")), :logoutput => true, :refreshonly => true, :subscribe => file, :title => "one" ) exec2 = Puppet::Type.type(:exec).new( :path => ENV["PATH"], :command => touch(newfile), :logoutput => true, :refreshonly => true, :subscribe => [file, exec1], :title => "two" ) exec1.stubs(:err) catalog = mk_catalog(file, exec1, exec2) catalog.apply FileTest.should be_exists(newfile) end - it "should still trigger skipped resources", :'fails_on_ruby_1.9.2' => true do + it "should still trigger skipped resources" do catalog = mk_catalog catalog.add_resource(*Puppet::Type.type(:schedule).mkdefaultschedules) Puppet[:ignoreschedules] = false file = Puppet::Type.type(:file).new( :name => tmpfile("file"), :ensure => "file", :backup => false ) fname = tmpfile("exec") exec = Puppet::Type.type(:exec).new( :name => touch(fname), :path => Puppet.features.microsoft_windows? ? "#{ENV['windir']}/system32" : "/usr/bin:/bin", :schedule => "monthly", :subscribe => Puppet::Resource.new("file", file.name) ) catalog.add_resource(file, exec) # Run it once catalog.apply FileTest.should be_exists(fname) # Now remove it, so it can get created again File.unlink(fname) file[:content] = "some content" catalog.apply FileTest.should be_exists(fname) # Now remove it, so it can get created again File.unlink(fname) # And tag our exec exec.tag("testrun") # And our file, so it runs file.tag("norun") Puppet[:tags] = "norun" file[:content] = "totally different content" catalog.apply FileTest.should be_exists(fname) end it "should not attempt to evaluate resources with failed dependencies" do exec = Puppet::Type.type(:exec).new( :command => "#{File.expand_path('/bin/mkdir')} /this/path/cannot/possibly/exist", :title => "mkdir" ) file1 = Puppet::Type.type(:file).new( :title => "file1", :path => tmpfile("file1"), :require => exec, :ensure => :file ) file2 = Puppet::Type.type(:file).new( :title => "file2", :path => tmpfile("file2"), :require => file1, :ensure => :file ) catalog = mk_catalog(exec, file1, file2) catalog.apply FileTest.should_not be_exists(file1[:path]) FileTest.should_not be_exists(file2[:path]) end it "should not trigger subscribing resources on failure" do file1 = tmpfile("file1") file2 = tmpfile("file2") create_file1 = Puppet::Type.type(:exec).new( :command => usr_bin_touch(file1) ) exec = Puppet::Type.type(:exec).new( :command => "#{File.expand_path('/bin/mkdir')} /this/path/cannot/possibly/exist", :title => "mkdir", :notify => create_file1 ) create_file2 = Puppet::Type.type(:exec).new( :command => usr_bin_touch(file2), :subscribe => exec ) catalog = mk_catalog(exec, create_file1, create_file2) catalog.apply FileTest.should_not be_exists(file1) FileTest.should_not be_exists(file2) end # #801 -- resources only checked in noop should be rescheduled immediately. it "should immediately reschedule noop resources" do Puppet::Type.type(:schedule).mkdefaultschedules resource = Puppet::Type.type(:notify).new(:name => "mymessage", :noop => true) catalog = Puppet::Resource::Catalog.new catalog.add_resource resource trans = catalog.apply trans.resource_harness.should be_scheduled(trans.resource_status(resource), resource) end end diff --git a/spec/integration/util/file_locking_spec.rb b/spec/integration/util/file_locking_spec.rb deleted file mode 100755 index 624ba033c..000000000 --- a/spec/integration/util/file_locking_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env rspec -require 'spec_helper' - -require 'puppet/util/file_locking' - -describe Puppet::Util::FileLocking, :'fails_on_ruby_1.9.2' => true do - before :each do - @file = Tempfile.new("puppetspec") - filepath = @file.path - @file.close!() - @file = filepath - @data = {:a => :b, :c => "A string", :d => "another string", :e => %w{an array of strings}} - File.open(@file, "w") { |f| f.puts YAML.dump(@data) } - end - - it "should be able to keep file corruption from happening when there are multiple writers threads" do - threads = [] - sync = Sync.new - 9.times { |a| - threads << Thread.new { - 9.times { |b| - sync.synchronize(Sync::SH) { - Puppet::Util::FileLocking.readlock(@file) { |f| - YAML.load(f.read).should == @data - } - } - sleep 0.01 - sync.synchronize(Sync::EX) { - Puppet::Util::FileLocking.writelock(@file) { |f| - f.puts YAML.dump(@data) - } - } - } - } - } - threads.each { |th| th.join } - end - - it "should be able to keep file corruption from happening when there are multiple writers processes" do - unless Process.fork - 50.times { |b| - Puppet::Util::FileLocking.writelock(@file) { |f| - f.puts YAML.dump(@data) - } - sleep 0.01 - } - Kernel.exit! - end - - 50.times { |c| - Puppet::Util::FileLocking.readlock(@file) { |f| - YAML.load(f.read).should == @data - } - } - end -end diff --git a/spec/integration/util/rdoc/parser_spec.rb b/spec/integration/util/rdoc/parser_spec.rb index bf1f0d268..90dab749f 100755 --- a/spec/integration/util/rdoc/parser_spec.rb +++ b/spec/integration/util/rdoc/parser_spec.rb @@ -1,58 +1,60 @@ #!/usr/bin/env rspec require 'spec_helper' -require 'puppet/resource/type_collection' -require 'puppet/util/rdoc/parser' -require 'puppet/util/rdoc' -require 'puppet/util/rdoc/code_objects' -require 'rdoc/options' -require 'rdoc/rdoc' - -describe RDoc::Parser, :'fails_on_ruby_1.9.2' => true do +describe "RDoc::Parser", :if => Puppet.features.rdoc1? do require 'puppet_spec/files' include PuppetSpec::Files + before :all do + require 'puppet/resource/type_collection' + require 'puppet/util/rdoc/parser' + require 'puppet/util/rdoc' + require 'puppet/util/rdoc/code_objects' + require 'rdoc/options' + require 'rdoc/rdoc' + end + before :each do tmpdir = tmpfile('rdoc_parser_tmp') Dir.mkdir(tmpdir) @parsedfile = File.join(tmpdir, 'init.pp') File.open(@parsedfile, 'w') do |f| f.puts '# comment' f.puts 'class ::test {}' end @top_level = stub_everything 'toplevel', :file_relative_name => @parsedfile @module = stub_everything 'module' @puppet_top_level = RDoc::PuppetTopLevel.new(@top_level) RDoc::PuppetTopLevel.stubs(:new).returns(@puppet_top_level) @puppet_top_level.expects(:add_module).returns(@module) @parser = RDoc::Parser.new(@top_level, @parsedfile, nil, Options.instance, RDoc::Stats.new) end after(:each) do File.unlink(@parsedfile) end def get_test_class(toplevel) # toplevel -> main -> test toplevel.classes[0].classes[0] end it "should parse to RDoc data structure" do @parser.expects(:document_class).with { |n,k,c| n == "::test" and k.is_a?(Puppet::Resource::Type) } @parser.scan end it "should get a PuppetClass for the main class" do @parser.scan.classes[0].should be_a(RDoc::PuppetClass) end it "should produce a PuppetClass whose name is test" do get_test_class(@parser.scan).name.should == "test" end it "should produce a PuppetClass whose comment is 'comment'" do get_test_class(@parser.scan).comment.should == "comment\n" end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7ca20d8e8..751e92763 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,131 +1,150 @@ dir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift File.join(dir, 'lib') # Don't want puppet getting the command line arguments for rake or autotest ARGV.clear require 'puppet' require 'mocha' gem 'rspec', '>=2.0.0' require 'rspec/expectations' # So everyone else doesn't have to include this base constant. module PuppetSpec FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR) end require 'pathname' require 'tmpdir' require 'puppet_spec/verbose' require 'puppet_spec/files' require 'puppet_spec/settings' require 'puppet_spec/fixtures' require 'puppet_spec/matchers' require 'puppet_spec/database' require 'monkey_patches/alias_should_to_must' require 'monkey_patches/publicize_methods' Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour| require behaviour.relative_path_from(Pathname.new(dir)) end RSpec.configure do |config| include PuppetSpec::Fixtures config.mock_with :mocha config.before :each do # Disabling garbage collection inside each test, and only running it at # the end of each block, gives us an ~ 15 percent speedup, and more on # some platforms *cough* windows *cough* that are a little slower. GC.disable # We need to preserve the current state of all our indirection cache and # terminus classes. This is pretty important, because changes to these # are global and lead to order dependencies in our testing. # # We go direct to the implementation because there is no safe, sane public # API to manage restoration of these to their default values. This # should, once the value is proved, be moved to a standard API on the # indirector. # # To make things worse, a number of the tests stub parts of the # indirector. These stubs have very specific expectations that what # little of the public API we could use is, well, likely to explode # randomly in some tests. So, direct access. --daniel 2011-08-30 $saved_indirection_state = {} indirections = Puppet::Indirector::Indirection.send(:class_variable_get, :@@indirections) indirections.each do |indirector| $saved_indirection_state[indirector.name] = { :@terminus_class => indirector.instance_variable_get(:@terminus_class), :@cache_class => indirector.instance_variable_get(:@cache_class) } end + # The process environment is a shared, persistent resource. + $old_env = ENV.to_hash + + # So is the load_path + $old_load_path = $LOAD_PATH.dup + # REVISIT: I think this conceals other bad tests, but I don't have time to # fully diagnose those right now. When you read this, please come tell me # I suck for letting this float. --daniel 2011-04-21 Signal.stubs(:trap) Puppet.settings.send(:initialize_everything_for_tests) # Longer keys are secure, but they sure make for some slow testing - both # in terms of generating keys, and in terms of anything the next step down # the line doing validation or whatever. Most tests don't care how long # or secure it is, just that it exists, so these are better and faster # defaults, in testing only. # # I would make these even shorter, but OpenSSL doesn't support anything # below 512 bits. Sad, really, because a 0 bit key would be just fine. Puppet[:req_bits] = 512 Puppet[:keylength] = 512 @logs = [] Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs)) @log_level = Puppet::Util::Log.level end config.after :each do Puppet.settings.send(:clear_everything_for_tests) Puppet::Node::Environment.clear Puppet::Util::Storage.clear Puppet::Util::ExecutionStub.reset PuppetSpec::Files.cleanup @logs.clear Puppet::Util::Log.close_all Puppet::Util::Log.level = @log_level Puppet.clear_deprecation_warnings # uncommenting and manipulating this can be useful when tracking down calls to deprecated code #Puppet.log_deprecations_to_file("deprecations.txt", /^Puppet::Util.exec/) # Restore the indirector configuration. See before hook. indirections = Puppet::Indirector::Indirection.send(:class_variable_get, :@@indirections) indirections.each do |indirector| $saved_indirection_state.fetch(indirector.name, {}).each do |variable, value| indirector.instance_variable_set(variable, value) end end $saved_indirection_state = {} + # Restore the global process environment. Can't just assign because this + # is a magic variable, sadly, and doesn't do that™. It is sufficiently + # faster to use the compare-then-set model to avoid excessive work that it + # justifies the complexity. --daniel 2012-03-15 + unless ENV.to_hash == $old_env + ENV.clear + $old_env.each {|k, v| ENV[k] = v } + end + # Some tests can cause us to connect, in which case the lingering # connection is a resource that can cause unexpected failure in later # tests, as well as sharing state accidentally. # We're testing if ActiveRecord::Base is defined because some test cases # may stub Puppet.features.rails? which is how we should normally # introspect for this functionality. ActiveRecord::Base.remove_connection if defined?(ActiveRecord::Base) + # Restore the load_path late, to avoid messing with stubs from the test. + $LOAD_PATH.clear + $old_load_path.each {|x| $LOAD_PATH << x } + # This will perform a GC between tests, but only if actually required. We # experimented with forcing a GC run, and that was less efficient than # just letting it run all the time. GC.enable end end diff --git a/spec/unit/application/face_base_spec.rb b/spec/unit/application/face_base_spec.rb index c50117ffc..5edac6cbb 100755 --- a/spec/unit/application/face_base_spec.rb +++ b/spec/unit/application/face_base_spec.rb @@ -1,394 +1,394 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/application/face_base' require 'tmpdir' class Puppet::Application::FaceBase::Basetest < Puppet::Application::FaceBase end describe Puppet::Application::FaceBase do let :app do app = Puppet::Application::FaceBase::Basetest.new app.command_line.stubs(:subcommand_name).returns('subcommand') Puppet::Util::Log.stubs(:newdestination) app end describe "#find_global_settings_argument" do it "should not match --ca to --ca-location" do option = mock('ca option', :optparse_args => ["--ca"]) Puppet.settings.expects(:each).yields(:ca, option) app.find_global_settings_argument("--ca-location").should be_nil end end describe "#parse_options" do before :each do app.command_line.stubs(:args).returns %w{} end describe "with just an action" do before :all do # We have to stub Signal.trap to avoid a crazy mess where we take # over signal handling and make it impossible to cancel the test # suite run. # # It would be nice to fix this elsewhere, but it is actually hard to # capture this in rspec 2.5 and all. :( --daniel 2011-04-08 Signal.stubs(:trap) app.command_line.stubs(:args).returns %w{foo} app.preinit app.parse_options end it "should set the face based on the type" do app.face.name.should == :basetest end it "should find the action" do app.action.should be app.action.name.should == :foo end end it "should stop if the first thing found is not an action" do app.command_line.stubs(:args).returns %w{banana count_args} expect { app.run }.to exit_with 1 @logs.first.should_not be_nil @logs.first.message.should =~ /has no 'banana' action/ end it "should use the default action if not given any arguments" do app.command_line.stubs(:args).returns [] action = stub(:options => [], :render_as => nil) Puppet::Face[:basetest, '0.0.1'].expects(:get_default_action).returns(action) app.stubs(:main) app.run app.action.should == action app.arguments.should == [ { } ] end it "should use the default action if not given a valid one" do app.command_line.stubs(:args).returns %w{bar} action = stub(:options => [], :render_as => nil) Puppet::Face[:basetest, '0.0.1'].expects(:get_default_action).returns(action) app.stubs(:main) app.run app.action.should == action app.arguments.should == [ 'bar', { } ] end it "should have no action if not given a valid one and there is no default action" do app.command_line.stubs(:args).returns %w{bar} Puppet::Face[:basetest, '0.0.1'].expects(:get_default_action).returns(nil) app.stubs(:main) expect { app.run }.to exit_with 1 @logs.first.message.should =~ /has no 'bar' action./ end [%w{something_I_cannot_do}, %w{something_I_cannot_do argument}].each do |input| it "should report unknown actions nicely" do app.command_line.stubs(:args).returns input Puppet::Face[:basetest, '0.0.1'].expects(:get_default_action).returns(nil) app.stubs(:main) expect { app.run }.to exit_with 1 @logs.first.message.should =~ /has no 'something_I_cannot_do' action/ end end [%w{something_I_cannot_do --unknown-option}, %w{something_I_cannot_do argument --unknown-option}].each do |input| it "should report unknown actions even if there are unknown options" do app.command_line.stubs(:args).returns input Puppet::Face[:basetest, '0.0.1'].expects(:get_default_action).returns(nil) app.stubs(:main) expect { app.run }.to exit_with 1 @logs.first.message.should =~ /has no 'something_I_cannot_do' action/ end end it "should report a sensible error when options with = fail" do app.command_line.stubs(:args).returns %w{--action=bar foo} expect { app.preinit; app.parse_options }. to raise_error OptionParser::InvalidOption, /invalid option: --action/ end it "should fail if an action option is before the action" do app.command_line.stubs(:args).returns %w{--action foo} expect { app.preinit; app.parse_options }. to raise_error OptionParser::InvalidOption, /invalid option: --action/ end it "should fail if an unknown option is before the action" do app.command_line.stubs(:args).returns %w{--bar foo} expect { app.preinit; app.parse_options }. to raise_error OptionParser::InvalidOption, /invalid option: --bar/ end it "should fail if an unknown option is after the action" do app.command_line.stubs(:args).returns %w{foo --bar} expect { app.preinit; app.parse_options }. to raise_error OptionParser::InvalidOption, /invalid option: --bar/ end it "should accept --bar as an argument to a mandatory option after action" do app.command_line.stubs(:args).returns %w{foo --mandatory --bar} app.preinit app.parse_options app.action.name.should == :foo app.options.should == { :mandatory => "--bar" } end it "should accept --bar as an argument to a mandatory option before action" do app.command_line.stubs(:args).returns %w{--mandatory --bar foo} app.preinit app.parse_options app.action.name.should == :foo app.options.should == { :mandatory => "--bar" } end it "should not skip when --foo=bar is given" do app.command_line.stubs(:args).returns %w{--mandatory=bar --bar foo} expect { app.preinit; app.parse_options }. to raise_error OptionParser::InvalidOption, /invalid option: --bar/ end { "boolean options before" => %w{--trace foo}, "boolean options after" => %w{foo --trace} }.each do |name, args| it "should accept global boolean settings #{name} the action" do app.command_line.stubs(:args).returns args app.command_line.send(:parse_global_options) app.preinit app.parse_options Puppet[:trace].should be_true end end { "before" => %w{--syslogfacility user1 foo}, " after" => %w{foo --syslogfacility user1} }.each do |name, args| it "should accept global settings with arguments #{name} the action" do app.command_line.stubs(:args).returns args app.command_line.send(:parse_global_options) app.preinit app.parse_options Puppet[:syslogfacility].should == "user1" end end - it "should handle application-level options", :'fails_on_ruby_1.9.2' => true do + it "should handle application-level options" do app.command_line.stubs(:args).returns %w{--verbose return_true} app.command_line.send(:parse_global_options) app.preinit app.parse_options app.face.name.should == :basetest end end describe "#setup" do it "should remove the action name from the arguments" do app.command_line.stubs(:args).returns %w{--mandatory --bar foo} app.command_line.send(:parse_global_options) app.preinit app.parse_options app.setup app.arguments.should == [{ :mandatory => "--bar" }] end it "should pass positional arguments" do app.command_line.stubs(:args).returns %w{--mandatory --bar foo bar baz quux} app.command_line.send(:parse_global_options) app.preinit app.parse_options app.setup app.arguments.should == ['bar', 'baz', 'quux', { :mandatory => "--bar" }] end end describe "#main" do before :each do app.stubs(:puts) # don't dump text to screen. app.face = Puppet::Face[:basetest, '0.0.1'] app.action = app.face.get_action(:foo) app.arguments = ["myname", "myarg"] end it "should send the specified verb and name to the face" do app.face.expects(:foo).with(*app.arguments) expect { app.main }.to exit_with 0 end it "should lookup help when it cannot do anything else" do app.action = nil Puppet::Face[:help, :current].expects(:help).with(:basetest) expect { app.main }.to exit_with 1 end it "should use its render method to render any result" do app.expects(:render).with(app.arguments.length + 1, ["myname", "myarg"]) expect { app.main }.to exit_with 0 end end describe "error reporting" do before :each do app.stubs(:puts) # don't dump text to screen. app.render_as = :json app.face = Puppet::Face[:basetest, '0.0.1'] app.arguments = [{}] # we always have options in there... end it "should exit 0 when the action returns true" do app.action = app.face.get_action :return_true expect { app.main }.to exit_with 0 end it "should exit 0 when the action returns false" do app.action = app.face.get_action :return_false expect { app.main }.to exit_with 0 end it "should exit 0 when the action returns nil" do app.action = app.face.get_action :return_nil expect { app.main }.to exit_with 0 end it "should exit non-0 when the action raises" do app.action = app.face.get_action :return_raise expect { app.main }.not_to exit_with 0 end it "should use the exit code set by the action" do app.action = app.face.get_action :with_specific_exit_code expect { app.main }.to exit_with 5 end end describe "#render" do before :each do app.face = Puppet::Face[:basetest, '0.0.1'] app.action = app.face.get_action(:foo) end context "default rendering" do before :each do app.setup end ["hello", 1, 1.0].each do |input| it "should just return a #{input.class.name}" do app.render(input, {}).should == input end end [[1, 2], ["one"], [{ 1 => 1 }]].each do |input| it "should render #{input.class} using JSON" do app.render(input, {}).should == input.to_pson.chomp end end it "should render a non-trivially-keyed Hash with using JSON" do hash = { [1,2] => 3, [2,3] => 5, [3,4] => 7 } app.render(hash, {}).should == hash.to_pson.chomp end it "should render a {String,Numeric}-keyed Hash into a table" do object = Object.new hash = { "one" => 1, "two" => [], "three" => {}, "four" => object, 5 => 5, 6.0 => 6 } # Gotta love ASCII-betical sort order. Hope your objects are better # structured for display than my test one is. --daniel 2011-04-18 app.render(hash, {}).should == < { "1" => '1' * 40, "2" => '2' * 40, '3' => '3' * 40 }, "text" => { "a" => 'a' * 40, 'b' => 'b' * 40, 'c' => 'c' * 40 } } app.render(hash, {}).should == <"1111111111111111111111111111111111111111", "2"=>"2222222222222222222222222222222222222222", "3"=>"3333333333333333333333333333333333333333"} text {"a"=>"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "b"=>"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "c"=>"cccccccccccccccccccccccccccccccccccccccc"} EOT end describe "when setting the rendering method" do after do # need to reset the when_rendering block so that other tests can set it later app.action.instance_variable_set("@when_rendering", {}) end it "should invoke the action rendering hook while rendering" do app.action.set_rendering_method_for(:console, proc { |value| "bi-winning!" }) app.render("bi-polar?", {}).should == "bi-winning!" end it "should invoke the action rendering hook with args and options while rendering" do app.action.instance_variable_set("@when_rendering", {}) app.action.when_invoked = proc { |name, options| 'just need to match arity for rendering' } app.action.set_rendering_method_for( :console, proc { |value, name, options| "I'm #{name}, no wait, I'm #{options[:altername]}" } ) app.render("bi-polar?", ['bob', {:altername => 'sue'}]).should == "I'm bob, no wait, I'm sue" end end it "should render JSON when asked for json" do app.render_as = :json json = app.render({ :one => 1, :two => 2 }, {}) json.should =~ /"one":\s*1\b/ json.should =~ /"two":\s*2\b/ PSON.parse(json).should == { "one" => 1, "two" => 2 } end end it "should fail early if asked to render an invalid format" do app.command_line.stubs(:args).returns %w{--render-as interpretive-dance return_true} app.command_line.send(:parse_global_options) # We shouldn't get here, thanks to the exception, and our expectation on # it, but this helps us fail if that slips up and all. --daniel 2011-04-27 Puppet::Face[:help, :current].expects(:help).never Puppet.expects(:err).with("Could not parse application options: I don't know how to render 'interpretive-dance'") expect { app.run }.to exit_with 1 #expect { # expect { app.run }.to exit_with 1 #}.to have_printed(/I don't know how to render 'interpretive-dance'/) end it "should work if asked to render a NetworkHandler format" do app.command_line.stubs(:args).returns %w{count_args a b c --render-as yaml} expect { expect { app.run }.to exit_with 0 }.to have_printed(/--- 3/) end it "should invoke when_rendering hook 's' when asked to render-as 's'" do app.command_line.stubs(:args).returns %w{with_s_rendering_hook --render-as s} app.action = app.face.get_action(:with_s_rendering_hook) expect { expect { app.run }.to exit_with 0 }.to have_printed(/you invoked the 's' rendering hook/) end end end diff --git a/spec/unit/application/facts_spec.rb b/spec/unit/application/facts_spec.rb index 7a7c36597..00f79fb67 100755 --- a/spec/unit/application/facts_spec.rb +++ b/spec/unit/application/facts_spec.rb @@ -1,28 +1,28 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/application/facts' describe Puppet::Application::Facts do before :each do subject.command_line.stubs(:subcommand_name).returns 'facts' end it "should fail if no key is given to find" do subject.command_line.stubs(:args).returns %w{find} expect { expect { subject.run }.to exit_with 1 }.to have_printed /err: puppet facts find takes 1 argument, but you gave 0/ @logs.first.to_s.should =~ /puppet facts find takes 1 argument, but you gave 0/ end - it "should return facts if a key is given to find", :'fails_on_ruby_1.9.2' => true do + it "should return facts if a key is given to find" do Puppet::Node::Facts.indirection.reset_terminus_class subject.command_line.stubs(:args).returns %w{find whatever --render-as yaml} expect { expect { subject.run }.to exit_with 0 }.should have_printed(/object:Puppet::Node::Facts/) @logs.should be_empty end end diff --git a/spec/unit/application/inspect_spec.rb b/spec/unit/application/inspect_spec.rb index 58eff023a..13db4123c 100755 --- a/spec/unit/application/inspect_spec.rb +++ b/spec/unit/application/inspect_spec.rb @@ -1,284 +1,285 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/application/inspect' require 'puppet/resource/catalog' require 'puppet/indirector/catalog/yaml' require 'puppet/indirector/report/rest' require 'puppet/indirector/file_bucket_file/rest' describe Puppet::Application::Inspect do include PuppetSpec::Files before :each do @inspect = Puppet::Application[:inspect] @inspect.preinit end it "should operate in agent run_mode" do @inspect.class.run_mode.name.should == :agent end describe "during setup" do it "should print its configuration if asked" do Puppet[:configprint] = "all" Puppet.settings.expects(:print_configs).returns(true) expect { @inspect.setup }.to exit_with 0 end it "should fail if reporting is turned off" do Puppet[:report] = false lambda { @inspect.setup }.should raise_error(/report=true/) end end describe "when executing" do before :each do Puppet[:report] = true @inspect.options[:logset] = true Puppet::Transaction::Report::Rest.any_instance.stubs(:save) @inspect.setup end it "should retrieve the local catalog" do Puppet::Resource::Catalog::Yaml.any_instance.expects(:find).with {|request| request.key == Puppet[:certname] }.returns(Puppet::Resource::Catalog.new) @inspect.run_command end it "should save the report to REST" do Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(Puppet::Resource::Catalog.new) Puppet::Transaction::Report::Rest.any_instance.expects(:save).with {|request| request.instance.host == Puppet[:certname] } @inspect.run_command end it "should audit the specified properties" do catalog = Puppet::Resource::Catalog.new file = Tempfile.new("foo") file.binmode file.puts("file contents") file.close resource = Puppet::Resource.new(:file, file.path, :parameters => {:audit => "all"}) catalog.add_resource(resource) Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog) events = nil Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request| events = request.instance.resource_statuses.values.first.events end @inspect.run_command properties = events.inject({}) do |property_values, event| property_values.merge(event.property => event.previous_value) end properties["ensure"].should == :file properties["content"].should == "{md5}#{Digest::MD5.hexdigest("file contents\n")}" properties.has_key?("target").should == false end it "should set audited to true for all events" do catalog = Puppet::Resource::Catalog.new file = Tempfile.new("foo") resource = Puppet::Resource.new(:file, file.path, :parameters => {:audit => "all"}) catalog.add_resource(resource) Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog) events = nil Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request| events = request.instance.resource_statuses.values.first.events end @inspect.run_command events.each do |event| event.audited.should == true end end it "should not report irrelevent attributes if the resource is absent" do catalog = Puppet::Resource::Catalog.new file = Tempfile.new("foo") resource = Puppet::Resource.new(:file, file.path, :parameters => {:audit => "all"}) file.close file.delete catalog.add_resource(resource) Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(catalog) events = nil Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request| events = request.instance.resource_statuses.values.first.events end @inspect.run_command properties = events.inject({}) do |property_values, event| property_values.merge(event.property => event.previous_value) end properties.should == {"ensure" => :absent} end describe "when archiving to a bucket" do before :each do Puppet[:archive_files] = true Puppet[:archive_file_server] = "filebucketserver" @catalog = Puppet::Resource::Catalog.new Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(@catalog) end describe "when auditing files" do before :each do @file = tmpfile("foo") @resource = Puppet::Resource.new(:file, @file, :parameters => {:audit => "content"}) @catalog.add_resource(@resource) end it "should send an existing file to the file bucket" do File.open(@file, 'w') { |f| f.write('stuff') } Puppet::FileBucketFile::Rest.any_instance.expects(:head).with do |request| request.server == Puppet[:archive_file_server] end.returns(false) Puppet::FileBucketFile::Rest.any_instance.expects(:save).with do |request| request.server == Puppet[:archive_file_server] and request.instance.contents == 'stuff' end @inspect.run_command end it "should not send unreadable files", :unless => Puppet.features.microsoft_windows? do File.open(@file, 'w') { |f| f.write('stuff') } File.chmod(0, @file) Puppet::FileBucketFile::Rest.any_instance.expects(:head).never Puppet::FileBucketFile::Rest.any_instance.expects(:save).never @inspect.run_command end it "should not try to send non-existent files" do Puppet::FileBucketFile::Rest.any_instance.expects(:head).never Puppet::FileBucketFile::Rest.any_instance.expects(:save).never @inspect.run_command end it "should not try to send files whose content we are not auditing" do @resource[:audit] = "group" Puppet::FileBucketFile::Rest.any_instance.expects(:head).never Puppet::FileBucketFile::Rest.any_instance.expects(:save).never @inspect.run_command end it "should continue if bucketing a file fails" do File.open(@file, 'w') { |f| f.write('stuff') } Puppet::FileBucketFile::Rest.any_instance.stubs(:head).returns false Puppet::FileBucketFile::Rest.any_instance.stubs(:save).raises "failure" Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request| @report = request.instance end @inspect.run_command @report.logs.first.should_not == nil @report.logs.first.message.should =~ /Could not back up/ end end describe "when auditing non-files" do before :each do Puppet::Type.newtype(:stub_type) do newparam(:name) do desc "The name var" isnamevar end newproperty(:content) do desc "content" def retrieve :whatever end end end @resource = Puppet::Resource.new(:stub_type, 'foo', :parameters => {:audit => "all"}) @catalog.add_resource(@resource) end after :each do Puppet::Type.rmtype(:stub_type) end it "should not try to send non-files" do Puppet::FileBucketFile::Rest.any_instance.expects(:head).never Puppet::FileBucketFile::Rest.any_instance.expects(:save).never @inspect.run_command end end end describe "when there are failures" do before :each do Puppet::Type.newtype(:stub_type) do newparam(:name) do desc "The name var" isnamevar end newproperty(:content) do desc "content" def retrieve raise "failed" end end end @catalog = Puppet::Resource::Catalog.new Puppet::Resource::Catalog::Yaml.any_instance.stubs(:find).returns(@catalog) Puppet::Transaction::Report::Rest.any_instance.expects(:save).with do |request| @report = request.instance end end after :each do Puppet::Type.rmtype(:stub_type) end it "should mark the report failed and create failed events for each property" do @resource = Puppet::Resource.new(:stub_type, 'foo', :parameters => {:audit => "all"}) @catalog.add_resource(@resource) @inspect.run_command @report.status.should == "failed" @report.logs.select{|log| log.message =~ /Could not inspect/}.size.should == 1 @report.resource_statuses.size.should == 1 @report.resource_statuses['Stub_type[foo]'].events.size.should == 1 event = @report.resource_statuses['Stub_type[foo]'].events.first event.property.should == "content" event.status.should == "failure" event.audited.should == true - event.instance_variables.should_not include("@previous_value") + event.instance_variables.should_not include "@previous_value" + event.instance_variables.should_not include :@previous_value end it "should continue to the next resource" do @resource = Puppet::Resource.new(:stub_type, 'foo', :parameters => {:audit => "all"}) @other_resource = Puppet::Resource.new(:stub_type, 'bar', :parameters => {:audit => "all"}) @catalog.add_resource(@resource) @catalog.add_resource(@other_resource) @inspect.run_command @report.resource_statuses.size.should == 2 @report.resource_statuses.keys.should =~ ['Stub_type[foo]', 'Stub_type[bar]'] end end end after :all do Puppet::Resource::Catalog.indirection.reset_terminus_class Puppet::Transaction::Report.indirection.terminus_class = :processor end end diff --git a/spec/unit/application/resource_spec.rb b/spec/unit/application/resource_spec.rb index 20b1d54c4..bc9474018 100755 --- a/spec/unit/application/resource_spec.rb +++ b/spec/unit/application/resource_spec.rb @@ -1,220 +1,220 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/application/resource' describe Puppet::Application::Resource do include PuppetSpec::Files before :each do @resource_app = Puppet::Application[:resource] Puppet::Util::Log.stubs(:newdestination) Puppet::Resource.indirection.stubs(:terminus_class=) end describe "in preinit" do - it "should init extra_params to empty array", :'fails_on_ruby_1.9.2' => true do + it "should init extra_params to empty array" do @resource_app.preinit @resource_app.extra_params.should == [] end it "should load Facter facts" do Facter.expects(:loadfacts).once @resource_app.preinit end end describe "when handling options" do [:debug, :verbose, :edit].each do |option| it "should store argument value when calling handle_#{option}" do @resource_app.options.expects(:[]=).with(option, 'arg') @resource_app.send("handle_#{option}".to_sym, 'arg') end end it "should set options[:host] to given host" do @resource_app.handle_host(:whatever) @resource_app.host.should == :whatever end it "should load an display all types with types option" do type1 = stub_everything 'type1', :name => :type1 type2 = stub_everything 'type2', :name => :type2 Puppet::Type.stubs(:loadall) Puppet::Type.stubs(:eachtype).multiple_yields(type1,type2) @resource_app.expects(:puts).with(['type1','type2']) expect { @resource_app.handle_types(nil) }.to exit_with 0 end it "should add param to extra_params list" do @resource_app.extra_params = [ :param1 ] @resource_app.handle_param("whatever") @resource_app.extra_params.should == [ :param1, :whatever ] end it "should get a parameter in the printed data if extra_params are passed" do tty = stub("tty", :tty? => true ) path = tmpfile('testfile') command_line = Puppet::Util::CommandLine.new("puppet", [ 'resource', 'file', path ], tty ) @resource_app.stubs(:command_line).returns command_line # provider is a parameter that should always be available @resource_app.extra_params = [ :provider ] expect { @resource_app.main }.to have_printed /provider\s+=>/ end end describe "during setup" do before :each do Puppet::Log.stubs(:newdestination) Puppet.stubs(:parse_config) end it "should set console as the log destination" do Puppet::Log.expects(:newdestination).with(:console) @resource_app.setup end it "should set log level to debug if --debug was passed" do @resource_app.options.stubs(:[]).with(:debug).returns(true) @resource_app.setup Puppet::Log.level.should == :debug end it "should set log level to info if --verbose was passed" do @resource_app.options.stubs(:[]).with(:debug).returns(false) @resource_app.options.stubs(:[]).with(:verbose).returns(true) @resource_app.setup Puppet::Log.level.should == :info end it "should Parse puppet config" do Puppet.expects(:parse_config) @resource_app.setup end end describe "when running" do before :each do @type = stub_everything 'type', :properties => [] @resource_app.command_line.stubs(:args).returns(['mytype']) Puppet::Type.stubs(:type).returns(@type) @res = stub_everything "resource" @res.stubs(:prune_parameters).returns(@res) @report = stub_everything "report" end it "should raise an error if no type is given" do @resource_app.command_line.stubs(:args).returns([]) lambda { @resource_app.main }.should raise_error(RuntimeError, "You must specify the type to display") end it "should raise an error when editing a remote host" do @resource_app.options.stubs(:[]).with(:edit).returns(true) @resource_app.host = 'host' lambda { @resource_app.main }.should raise_error(RuntimeError, "You cannot edit a remote host") end it "should raise an error if the type is not found" do Puppet::Type.stubs(:type).returns(nil) lambda { @resource_app.main }.should raise_error(RuntimeError, 'Could not find type mytype') end describe "with a host" do before :each do @resource_app.stubs(:puts) @resource_app.host = 'host' Puppet::Resource.indirection.stubs(:find ).never Puppet::Resource.indirection.stubs(:search).never Puppet::Resource.indirection.stubs(:save ).never end it "should search for resources" do @resource_app.command_line.stubs(:args).returns(['type']) Puppet::Resource.indirection.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([]) @resource_app.main end it "should describe the given resource" do @resource_app.command_line.stubs(:args).returns(['type', 'name']) Puppet::Resource.indirection.expects(:find).with('https://host:8139/production/resources/type/name').returns(@res) @resource_app.main end it "should add given parameters to the object" do @resource_app.command_line.stubs(:args).returns(['type','name','param=temp']) Puppet::Resource.indirection.expects(:save). with(@res, 'https://host:8139/production/resources/type/name'). returns([@res, @report]) Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(@res) @resource_app.main end end describe "without a host" do before :each do @resource_app.stubs(:puts) @resource_app.host = nil Puppet::Resource.indirection.stubs(:find ).never Puppet::Resource.indirection.stubs(:search).never Puppet::Resource.indirection.stubs(:save ).never end it "should search for resources" do Puppet::Resource.indirection.expects(:search).with('mytype/', {}).returns([]) @resource_app.main end it "should describe the given resource" do @resource_app.command_line.stubs(:args).returns(['type','name']) Puppet::Resource.indirection.expects(:find).with('type/name').returns(@res) @resource_app.main end it "should add given parameters to the object" do @resource_app.command_line.stubs(:args).returns(['type','name','param=temp']) Puppet::Resource.indirection.expects(:save).with(@res, 'type/name').returns([@res, @report]) Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(@res) @resource_app.main end end end describe "when handling file type" do before :each do Facter.stubs(:loadfacts) @resource_app.preinit end it "should raise an exception if no file specified" do @resource_app.command_line.stubs(:args).returns(['file']) lambda { @resource_app.main }.should raise_error(RuntimeError, /Listing all file instances is not supported/) end it "should output a file resource when given a file path" do path = File.expand_path('/etc') res = Puppet::Type.type(:file).new(:path => path).to_resource Puppet::Resource.indirection.expects(:find).returns(res) @resource_app.command_line.stubs(:args).returns(['file', path]) @resource_app.expects(:puts).with do |args| args.should =~ /file \{ '#{Regexp.escape(path)}'/m end @resource_app.main end end end diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 909b06339..0d78cb48b 100755 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -1,588 +1,602 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/application' require 'puppet' require 'getoptlong' +require 'timeout' describe Puppet::Application do before do Puppet::Util::Instrumentation.stubs(:init) @app = Class.new(Puppet::Application).new @appclass = @app.class @app.stubs(:name).returns("test_app") # avoid actually trying to parse any settings Puppet.settings.stubs(:parse) end describe "application defaults" do it "should fail if required app default values are missing" do @app.stubs(:app_defaults).returns({ :foo => 'bar' }) Puppet.expects(:err).with(regexp_matches(/missing required app default setting/)) expect { @app.run }.to exit_with 1 end end describe "finding" do before do @klass = Puppet::Application @klass.stubs(:puts) end it "should find classes in the namespace" do @klass.find("Agent").should == @klass::Agent end - it "should not find classes outside the namespace", :'fails_on_ruby_1.9.2' => true do + it "should not find classes outside the namespace" do expect { @klass.find("String") }.to exit_with 1 end it "should exit if it can't find a class" do - reg = "Unable to find application 'ThisShallNeverEverEverExist'. " - reg += "no such file to load -- puppet/application/thisshallneverevereverexist" - @klass.expects(:puts).with(reg) + @klass.expects(:puts).with do |value| + value =~ /Unable to find application 'ThisShallNeverEverEverExist'/ and + value =~ /puppet\/application\/thisshallneverevereverexist/ and + value =~ /no such file to load|cannot load such file/ + end expect { @klass.find("ThisShallNeverEverEverExist") }.to exit_with 1 end it "#12114: should prevent File namespace collisions" do # have to require the file face once, then the second time around it would fail @klass.find("File").should == Puppet::Application::File @klass.find("File").should == Puppet::Application::File end end describe ".run_mode" do it "should default to user" do @appclass.run_mode.name.should == :user end it "should set and get a value" do @appclass.run_mode :agent @appclass.run_mode.name.should == :agent end end # These tests may look a little weird and repetative in its current state; # it used to illustrate several ways that the run_mode could be changed # at run time; there are fewer ways now, but it would still be nice to # get to a point where it was entirely impossible. describe "when dealing with run_mode" do class TestApp < Puppet::Application run_mode :master def run_command # no-op end end it "should sadly and frighteningly allow run_mode to change at runtime via #initialize_app_defaults" do Puppet.features.stubs(:syslog?).returns(true) Puppet[:run_mode].should == :user expect { app = TestApp.new app.initialize_app_defaults Puppet[:run_mode].should == :master }.to_not raise_error end it "should sadly and frighteningly allow run_mode to change at runtime via #run" do expect { app = TestApp.new app.run app.class.run_mode.name.should == :master Puppet[:run_mode].should == :master }.should_not raise_error end end it "it should not allow initialize_app_defaults to be called multiple times" do app = Puppet::Application.new expect { app.initialize_app_defaults }.to_not raise_error expect { app.initialize_app_defaults }.to raise_error end it "should explode when an invalid run mode is set at runtime, for great victory" do class InvalidRunModeTestApp < Puppet::Application run_mode :abracadabra def run_command # no-op end end expect { app = InvalidRunModeTestApp.new app.initialize_app_defaults }.to raise_error end it "should have a run entry-point" do @app.should respond_to(:run) end it "should have a read accessor to options" do @app.should respond_to(:options) end it "should include a default setup method" do @app.should respond_to(:setup) end it "should include a default preinit method" do @app.should respond_to(:preinit) end it "should include a default run_command method" do @app.should respond_to(:run_command) end it "should invoke main as the default" do @app.expects( :main ) @app.run_command end it "should initialize the Puppet Instrumentation layer early in the life cycle" do startup_sequence = sequence('startup') @app.expects(:initialize_app_defaults).in_sequence(startup_sequence) Puppet::Util::Instrumentation.expects(:init).in_sequence(startup_sequence) @app.expects(:preinit).in_sequence(startup_sequence) expect { @app.run }.to exit_with(1) end describe 'when invoking clear!' do before :each do Puppet::Application.run_status = :stop_requested Puppet::Application.clear! end it 'should have nil run_status' do Puppet::Application.run_status.should be_nil end it 'should return false for restart_requested?' do Puppet::Application.restart_requested?.should be_false end it 'should return false for stop_requested?' do Puppet::Application.stop_requested?.should be_false end it 'should return false for interrupted?' do Puppet::Application.interrupted?.should be_false end it 'should return true for clear?' do Puppet::Application.clear?.should be_true end end describe 'after invoking stop!' do before :each do Puppet::Application.run_status = nil Puppet::Application.stop! end after :each do Puppet::Application.run_status = nil end it 'should have run_status of :stop_requested' do Puppet::Application.run_status.should == :stop_requested end it 'should return true for stop_requested?' do Puppet::Application.stop_requested?.should be_true end it 'should return false for restart_requested?' do Puppet::Application.restart_requested?.should be_false end it 'should return true for interrupted?' do Puppet::Application.interrupted?.should be_true end it 'should return false for clear?' do Puppet::Application.clear?.should be_false end end describe 'when invoking restart!' do before :each do Puppet::Application.run_status = nil Puppet::Application.restart! end after :each do Puppet::Application.run_status = nil end it 'should have run_status of :restart_requested' do Puppet::Application.run_status.should == :restart_requested end it 'should return true for restart_requested?' do Puppet::Application.restart_requested?.should be_true end it 'should return false for stop_requested?' do Puppet::Application.stop_requested?.should be_false end it 'should return true for interrupted?' do Puppet::Application.interrupted?.should be_true end it 'should return false for clear?' do Puppet::Application.clear?.should be_false end end describe 'when performing a controlled_run' do it 'should not execute block if not :clear?' do Puppet::Application.run_status = :stop_requested target = mock 'target' target.expects(:some_method).never Puppet::Application.controlled_run do target.some_method end end it 'should execute block if :clear?' do Puppet::Application.run_status = nil target = mock 'target' target.expects(:some_method).once Puppet::Application.controlled_run do target.some_method end end describe 'on POSIX systems', :if => Puppet.features.posix? do - it 'should signal process with HUP after block if restart requested during block execution', :'fails_on_ruby_1.9.2' => true do - Puppet::Application.run_status = nil - target = mock 'target' - target.expects(:some_method).once - old_handler = trap('HUP') { target.some_method } - begin - Puppet::Application.controlled_run do - Puppet::Application.run_status = :restart_requested + it 'should signal process with HUP after block if restart requested during block execution' do + Timeout::timeout(3) do # if the signal doesn't fire, this causes failure. + + has_run = false + old_handler = trap('HUP') { has_run = true } + + begin + Puppet::Application.controlled_run do + Puppet::Application.run_status = :restart_requested + end + + # Ruby 1.9 uses a separate OS level thread to run the signal + # handler, so we have to poll - ideally, in a way that will kick + # the OS into running other threads - for a while. + # + # You can't just use the Ruby Thread yield thing either, because + # that is just an OS hint, and Linux ... doesn't take that + # seriously. --daniel 2012-03-22 + sleep 0.001 while not has_run + ensure + trap('HUP', old_handler) end - ensure - trap('HUP', old_handler) end end end after :each do Puppet::Application.run_status = nil end end describe "when parsing command-line options" do before :each do @app.command_line.stubs(:args).returns([]) Puppet.settings.stubs(:optparse_addargs).returns([]) end it "should pass the banner to the option parser" do option_parser = stub "option parser" option_parser.stubs(:on) option_parser.stubs(:parse!) @app.class.instance_eval do banner "banner" end OptionParser.expects(:new).with("banner").returns(option_parser) @app.parse_options end it "should ask OptionParser to parse the command-line argument" do @app.command_line.stubs(:args).returns(%w{ fake args }) OptionParser.any_instance.expects(:parse!).with(%w{ fake args }) @app.parse_options end describe "when using --help" do it "should call exit" do @app.stubs(:puts) expect { @app.handle_help(nil) }.to exit_with 0 end end describe "when using --version" do it "should declare a version option" do @app.should respond_to(:handle_version) end it "should exit after printing the version" do @app.stubs(:puts) expect { @app.handle_version(nil) }.to exit_with 0 end end describe "when dealing with an argument not declared directly by the application" do it "should pass it to handle_unknown if this method exists" do Puppet.settings.stubs(:optparse_addargs).returns([["--not-handled", :REQUIRED]]) @app.expects(:handle_unknown).with("--not-handled", "value").returns(true) @app.command_line.stubs(:args).returns(["--not-handled", "value"]) @app.parse_options end it "should transform boolean option to normal form for Puppet.settings" do @app.expects(:handle_unknown).with("--option", true) @app.send(:handlearg, "--[no-]option", true) end it "should transform boolean option to no- form for Puppet.settings" do @app.expects(:handle_unknown).with("--no-option", false) @app.send(:handlearg, "--[no-]option", false) end end end describe "when calling default setup" do before :each do @app.options.stubs(:[]) end [ :debug, :verbose ].each do |level| it "should honor option #{level}" do @app.options.stubs(:[]).with(level).returns(true) Puppet::Util::Log.stubs(:newdestination) @app.setup Puppet::Util::Log.level.should == (level == :verbose ? :info : :debug) end end it "should honor setdest option" do @app.options.stubs(:[]).with(:setdest).returns(false) Puppet::Util::Log.expects(:setup_default) @app.setup end end describe "when configuring routes" do include PuppetSpec::Files before :each do Puppet::Node.indirection.reset_terminus_class end after :each do Puppet::Node.indirection.reset_terminus_class end it "should use the routes specified for only the active application" do Puppet[:route_file] = tmpfile('routes') File.open(Puppet[:route_file], 'w') do |f| f.print <<-ROUTES test_app: node: terminus: exec other_app: node: terminus: plain catalog: terminus: invalid ROUTES end @app.configure_indirector_routes Puppet::Node.indirection.terminus_class.should == 'exec' end it "should not fail if the route file doesn't exist" do Puppet[:route_file] = "/dev/null/non-existent" expect { @app.configure_indirector_routes }.should_not raise_error end it "should raise an error if the routes file is invalid" do Puppet[:route_file] = tmpfile('routes') File.open(Puppet[:route_file], 'w') do |f| f.print <<-ROUTES invalid : : yaml ROUTES end expect { @app.configure_indirector_routes }.should raise_error end end describe "when running" do before :each do @app.stubs(:preinit) @app.stubs(:setup) @app.stubs(:parse_options) end it "should call preinit" do @app.stubs(:run_command) @app.expects(:preinit) @app.run end it "should call parse_options" do @app.stubs(:run_command) @app.expects(:parse_options) @app.run end it "should call run_command" do @app.expects(:run_command) @app.run end it "should call run_command" do @app.expects(:run_command) @app.run end it "should call main as the default command" do @app.expects(:main) @app.run end it "should warn and exit if no command can be called" do Puppet.expects(:err) expect { @app.run }.to exit_with 1 end it "should raise an error if dispatch returns no command" do @app.stubs(:get_command).returns(nil) Puppet.expects(:err) expect { @app.run }.to exit_with 1 end it "should raise an error if dispatch returns an invalid command" do @app.stubs(:get_command).returns(:this_function_doesnt_exist) Puppet.expects(:err) expect { @app.run }.to exit_with 1 end end describe "when metaprogramming" do describe "when calling option" do it "should create a new method named after the option" do @app.class.option("--test1","-t") do end @app.should respond_to(:handle_test1) end it "should transpose in option name any '-' into '_'" do @app.class.option("--test-dashes-again","-t") do end @app.should respond_to(:handle_test_dashes_again) end it "should create a new method called handle_test2 with option(\"--[no-]test2\")" do @app.class.option("--[no-]test2","-t") do end @app.should respond_to(:handle_test2) end describe "when a block is passed" do it "should create a new method with it" do @app.class.option("--[no-]test2","-t") do raise "I can't believe it, it works!" end lambda { @app.handle_test2 }.should raise_error end it "should declare the option to OptionParser" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.expects(:on).with { |*arg| arg[0] == "--[no-]test3" } @app.class.option("--[no-]test3","-t") do end @app.parse_options end it "should pass a block that calls our defined method" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.stubs(:on).with('--test4','-t').yields(nil) @app.expects(:send).with(:handle_test4, nil) @app.class.option("--test4","-t") do end @app.parse_options end end describe "when no block is given" do it "should declare the option to OptionParser" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.expects(:on).with("--test4","-t") @app.class.option("--test4","-t") @app.parse_options end it "should give to OptionParser a block that adds the the value to the options array" do OptionParser.any_instance.stubs(:on) OptionParser.any_instance.stubs(:on).with("--test4","-t").yields(nil) @app.options.expects(:[]=).with(:test4,nil) @app.class.option("--test4","-t") @app.parse_options end end end end end diff --git a/spec/unit/configurer_spec.rb b/spec/unit/configurer_spec.rb index f14c85483..66c7f81fc 100755 --- a/spec/unit/configurer_spec.rb +++ b/spec/unit/configurer_spec.rb @@ -1,622 +1,631 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/configurer' describe Puppet::Configurer do before do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new @agent.stubs(:dostorage) Puppet::Util::Storage.stubs(:store) Puppet[:server] = "puppetmaster" Puppet[:report] = true end it "should include the Plugin Handler module" do Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::PluginHandler) end it "should include the Fact Handler module" do Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::FactHandler) end it "should use the puppetdlockfile as its lockfile path" do Puppet.settings.expects(:value).with(:puppetdlockfile).returns("/my/lock") Puppet::Configurer.lockfile_path.should == "/my/lock" end describe "when executing a pre-run hook" do it "should do nothing if the hook is set to an empty string" do Puppet.settings[:prerun_command] = "" Puppet::Util.expects(:exec).never @agent.execute_prerun_command end it "should execute any pre-run command provided via the 'prerun_command' setting" do Puppet.settings[:prerun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.execute_prerun_command end it "should fail if the command fails" do Puppet.settings[:prerun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.execute_prerun_command.should be_false end end describe "when executing a post-run hook" do it "should do nothing if the hook is set to an empty string" do Puppet.settings[:postrun_command] = "" Puppet::Util.expects(:exec).never @agent.execute_postrun_command end it "should execute any post-run command provided via the 'postrun_command' setting" do Puppet.settings[:postrun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.execute_postrun_command end it "should fail if the command fails" do Puppet.settings[:postrun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.execute_postrun_command.should be_false end end describe "when executing a catalog run" do before do Puppet.settings.stubs(:use).returns(true) @agent.stubs(:prepare) Puppet::Node::Facts.indirection.terminus_class = :memory @facts = Puppet::Node::Facts.new(Puppet[:node_name_value]) Puppet::Node::Facts.indirection.save(@facts) @catalog = Puppet::Resource::Catalog.new @catalog.stubs(:to_ral).returns(@catalog) Puppet::Resource::Catalog.indirection.terminus_class = :rest Puppet::Resource::Catalog.indirection.stubs(:find).returns(@catalog) @agent.stubs(:send_report) @agent.stubs(:save_last_run_summary) Puppet::Util::Log.stubs(:close_all) end after :all do Puppet::Node::Facts.indirection.reset_terminus_class Puppet::Resource::Catalog.indirection.reset_terminus_class end it "should prepare for the run" do @agent.expects(:prepare) @agent.run end it "should initialize a transaction report if one is not provided" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns report @agent.run end it "should respect node_name_fact when setting the host on a report" do Puppet[:node_name_fact] = 'my_name_fact' @facts.values = {'my_name_fact' => 'node_name_from_fact'} report = Puppet::Transaction::Report.new("apply") @agent.run(:report => report) report.host.should == 'node_name_from_fact' end it "should pass the new report to the catalog" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.stubs(:new).returns report @catalog.expects(:apply).with{|options| options[:report] == report} @agent.run end it "should use the provided report if it was passed one" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).never @catalog.expects(:apply).with{|options| options[:report] == report} @agent.run(:report => report) end it "should set the report as a log destination" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns report Puppet::Util::Log.expects(:newdestination).with(report) Puppet::Util::Log.expects(:close).with(report) @agent.run end it "should retrieve the catalog" do @agent.expects(:retrieve_catalog) @agent.run end it "should log a failure and do nothing if no catalog can be retrieved" do @agent.expects(:retrieve_catalog).returns nil Puppet.expects(:err).with "Could not retrieve catalog; skipping run" @agent.run end it "should apply the catalog with all options to :run" do @agent.expects(:retrieve_catalog).returns @catalog @catalog.expects(:apply).with { |args| args[:one] == true } @agent.run :one => true end it "should accept a catalog and use it instead of retrieving a different one" do @agent.expects(:retrieve_catalog).never @catalog.expects(:apply) @agent.run :one => true, :catalog => @catalog end it "should benchmark how long it takes to apply the catalog" do @agent.expects(:benchmark).with(:notice, "Finished catalog run") @agent.expects(:retrieve_catalog).returns @catalog @catalog.expects(:apply).never # because we're not yielding @agent.run end it "should execute post-run hooks after the run" do @agent.expects(:execute_postrun_command) @agent.run end it "should send the report" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) @agent.expects(:send_report).with(report) @agent.run end it "should send the transaction report even if the catalog could not be retrieved" do @agent.expects(:retrieve_catalog).returns nil report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) @agent.expects(:send_report) @agent.run end it "should send the transaction report even if there is a failure" do @agent.expects(:retrieve_catalog).raises "whatever" report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) @agent.expects(:send_report) @agent.run.should be_nil end it "should remove the report as a log destination when the run is finished" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) @agent.run Puppet::Util::Log.destinations.should_not include(report) end it "should return the report exit_status as the result of the run" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) report.expects(:exit_status).returns(1234) @agent.run.should == 1234 end it "should send the transaction report even if the pre-run command fails" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) Puppet.settings[:prerun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.expects(:send_report) @agent.run.should be_nil end it "should include the pre-run command failure in the report" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) Puppet.settings[:prerun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.run.should be_nil report.logs.find { |x| x.message =~ /Could not run command from prerun_command/ }.should be end it "should send the transaction report even if the post-run command fails" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) Puppet.settings[:postrun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @agent.expects(:send_report) @agent.run.should be_nil end it "should include the post-run command failure in the report" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) Puppet.settings[:postrun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") report.expects(:<<).with { |log| log.message.include?("Could not run command from postrun_command") } @agent.run.should be_nil end it "should execute post-run command even if the pre-run command fails" do Puppet.settings[:prerun_command] = "/my/precommand" Puppet.settings[:postrun_command] = "/my/postcommand" Puppet::Util::Execution.expects(:execute).with(["/my/precommand"]).raises(Puppet::ExecutionFailure, "Failed") Puppet::Util::Execution.expects(:execute).with(["/my/postcommand"]) @agent.run.should be_nil end it "should finalize the report" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) report.expects(:finalize_report) @agent.run end it "should not apply the catalog if the pre-run command fails" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) Puppet.settings[:prerun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @catalog.expects(:apply).never() @agent.expects(:send_report) @agent.run.should be_nil end it "should apply the catalog, send the report, and return nil if the post-run command fails" do report = Puppet::Transaction::Report.new("apply") Puppet::Transaction::Report.expects(:new).returns(report) Puppet.settings[:postrun_command] = "/my/command" Puppet::Util::Execution.expects(:execute).with(["/my/command"]).raises(Puppet::ExecutionFailure, "Failed") @catalog.expects(:apply) @agent.expects(:send_report) @agent.run.should be_nil end it "should refetch the catalog if the server specifies a new environment in the catalog" do @catalog.stubs(:environment).returns("second_env") @agent.expects(:prepare).twice @agent.expects(:retrieve_catalog).returns(@catalog).twice @agent.run end it "should change the environment setting if the server specifies a new environment in the catalog" do @catalog.stubs(:environment).returns("second_env") @agent.run Puppet[:environment].should == "second_env" end describe "when not using a REST terminus for catalogs" do it "should not pass any facts when retrieving the catalog" do Puppet::Resource::Catalog.indirection.terminus_class = :compiler @agent.expects(:facts_for_uploading).never Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:facts].nil? }.returns @catalog @agent.run end end describe "when using a REST terminus for catalogs" do it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do Puppet::Resource::Catalog.indirection.terminus_class = :rest @agent.expects(:facts_for_uploading).returns(:facts => "myfacts", :facts_format => :foo) Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:facts] == "myfacts" and options[:facts_format] == :foo }.returns @catalog @agent.run end end end describe "when sending a report" do include PuppetSpec::Files before do Puppet.settings.stubs(:use).returns(true) @configurer = Puppet::Configurer.new Puppet[:lastrunfile] = tmpfile('last_run_file') @report = Puppet::Transaction::Report.new("apply") end it "should print a report summary if configured to do so" do Puppet.settings[:summarize] = true @report.expects(:summary).returns "stuff" @configurer.expects(:puts).with("stuff") @configurer.send_report(@report) end it "should not print a report summary if not configured to do so" do Puppet.settings[:summarize] = false @configurer.expects(:puts).never @configurer.send_report(@report) end it "should save the report if reporting is enabled" do Puppet.settings[:report] = true Puppet::Transaction::Report.indirection.expects(:save).with(@report) @configurer.send_report(@report) end it "should not save the report if reporting is disabled" do Puppet.settings[:report] = false Puppet::Transaction::Report.indirection.expects(:save).with(@report).never @configurer.send_report(@report) end it "should save the last run summary if reporting is enabled" do Puppet.settings[:report] = true @configurer.expects(:save_last_run_summary).with(@report) @configurer.send_report(@report) end it "should save the last run summary if reporting is disabled" do Puppet.settings[:report] = false @configurer.expects(:save_last_run_summary).with(@report) @configurer.send_report(@report) end it "should log but not fail if saving the report fails" do Puppet.settings[:report] = true Puppet::Transaction::Report.indirection.expects(:save).raises("whatever") Puppet.expects(:err) lambda { @configurer.send_report(@report) }.should_not raise_error end end describe "when saving the summary report file" do include PuppetSpec::Files before do Puppet.settings.stubs(:use).returns(true) @configurer = Puppet::Configurer.new @report = stub 'report', :raw_summary => {} Puppet[:lastrunfile] = tmpfile('last_run_file') end it "should write the last run file" do @configurer.save_last_run_summary(@report) FileTest.exists?(Puppet[:lastrunfile]).should be_true end it "should write the raw summary as yaml" do @report.expects(:raw_summary).returns("summary") @configurer.save_last_run_summary(@report) File.read(Puppet[:lastrunfile]).should == YAML.dump("summary") end it "should log but not fail if saving the last run summary fails" do - Puppet::Util::FileLocking.expects(:writelock).raises "exception" + # The mock will raise an exception on any method used. This should + # simulate a nice hard failure from the underlying OS for us. + fh = Class.new(Object) do + def method_missing(*args) + raise "failed to do #{args[0]}" + end + end.new + + Puppet::Util.expects(:replace_file).yields(fh) + Puppet.expects(:err) - lambda { @configurer.save_last_run_summary(@report) }.should_not raise_error + expect { @configurer.save_last_run_summary(@report) }.should_not raise_error end end describe "when retrieving a catalog" do before do Puppet.settings.stubs(:use).returns(true) @agent.stubs(:facts_for_uploading).returns({}) @catalog = Puppet::Resource::Catalog.new # this is the default when using a Configurer instance Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :rest @agent.stubs(:convert_catalog).returns @catalog end describe "and configured to only retrieve a catalog from the cache" do before do Puppet.settings[:use_cached_catalog] = true end it "should first look in the cache for a catalog" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.never @agent.retrieve_catalog({}).should == @catalog end it "should compile a new catalog if none is found in the cache" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog({}).should == @catalog end end it "should use the Catalog class to get its catalog" do Puppet::Resource::Catalog.indirection.expects(:find).returns @catalog @agent.retrieve_catalog({}) end it "should use its node_name_value to retrieve the catalog" do Facter.stubs(:value).returns "eh" Puppet.settings[:node_name_value] = "myhost.domain.com" Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog @agent.retrieve_catalog({}) end it "should default to returning a catalog retrieved directly from the server, skipping the cache" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog({}).should == @catalog end it "should log and return the cached catalog when no catalog can be retrieved from the server" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog Puppet.expects(:notice) @agent.retrieve_catalog({}).should == @catalog end it "should not look in the cache for a catalog if one is returned from the server" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never @agent.retrieve_catalog({}).should == @catalog end it "should return the cached catalog when retrieving the remote catalog throws an exception" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh" Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog @agent.retrieve_catalog({}).should == @catalog end it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do Puppet.stubs(:[]) Puppet.expects(:[]).with(:usecacheonfailure).returns false Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet.expects(:warning) @agent.retrieve_catalog({}).should be_nil end it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil @agent.retrieve_catalog({}).should be_nil end it "should convert the catalog before returning" do Puppet::Resource::Catalog.indirection.stubs(:find).returns @catalog @agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog" @agent.retrieve_catalog({}).should == "converted catalog" end it "should return nil if there is an error while retrieving the catalog" do Puppet::Resource::Catalog.indirection.expects(:find).at_least_once.raises "eh" @agent.retrieve_catalog({}).should be_nil end end describe "when converting the catalog" do before do Puppet.settings.stubs(:use).returns(true) @catalog = Puppet::Resource::Catalog.new @oldcatalog = stub 'old_catalog', :to_ral => @catalog end it "should convert the catalog to a RAL-formed catalog" do @oldcatalog.expects(:to_ral).returns @catalog @agent.convert_catalog(@oldcatalog, 10).should equal(@catalog) end it "should finalize the catalog" do @catalog.expects(:finalize) @agent.convert_catalog(@oldcatalog, 10) end it "should record the passed retrieval time with the RAL catalog" do @catalog.expects(:retrieval_duration=).with 10 @agent.convert_catalog(@oldcatalog, 10) end it "should write the RAL catalog's class file" do @catalog.expects(:write_class_file) @agent.convert_catalog(@oldcatalog, 10) end it "should write the RAL catalog's resource file" do @catalog.expects(:write_resource_file) @agent.convert_catalog(@oldcatalog, 10) end end describe "when preparing for a run" do before do Puppet.settings.stubs(:use).returns(true) @facts = {"one" => "two", "three" => "four"} end it "should initialize the metadata store" do @agent.class.stubs(:facts).returns(@facts) @agent.expects(:dostorage) @agent.prepare({}) end it "should download plugins" do @agent.expects(:download_plugins) @agent.prepare({}) end end end diff --git a/spec/unit/indirector/facts/couch_spec.rb b/spec/unit/indirector/facts/couch_spec.rb index 7038a438d..d0862486c 100755 --- a/spec/unit/indirector/facts/couch_spec.rb +++ b/spec/unit/indirector/facts/couch_spec.rb @@ -1,102 +1,102 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/node/facts' require 'puppet/indirector/facts/couch' -describe "Puppet::Node::Facts::Couch", :'fails_on_ruby_1.9.2' => true do +describe "Puppet::Node::Facts::Couch" do describe "when couchdb is not available", :unless => Puppet.features.couchdb? do it "should fail to initialize" do lambda { Puppet::Node::Facts::Couch.new }.should raise_error end end - describe "when couchdb is available", :if => Puppet.features.couchdb?, :'fails_on_ruby_1.9.2' => true do + describe "when couchdb is available", :if => Puppet.features.couchdb? do before do @mock_db = mock('couch db') mock_document = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.values) mock_document.stubs(:database).returns(@mock_db) @mock_db.stubs(:get).with(fake_request.key).returns(mock_document) Puppet::Node::Facts::Couch.stubs(:db).returns(@mock_db) end subject { Puppet::Node::Facts::Couch } describe "#find" do describe "when the node document exists" do it "should find the request by key" do @mock_db.expects(:get).with(fake_request.key).returns({'_id' => fake_request.key, 'facts' => fake_request.instance.values}) subject.new.find(fake_request).should == fake_request.instance end end describe "when the node document does not exist" do before do @mock_db.expects(:get). with(fake_request.key). raises(RestClient::ResourceNotFound) end it "should return nil" do subject.new.find(fake_request).should be_nil end it "should send Puppet a debug message" do Puppet.expects(:debug).with("No couchdb document with id: test.local") subject.new.find(fake_request).should be_nil end end end describe "#save" do describe "with options" do subject do lambda { Puppet::Node::Facts::Couch.new.save(fake_request([1])) } end it { should raise_error(ArgumentError, "PUT does not accept options") } end it "should save the json to the CouchDB database" do @mock_db.expects(:save_doc).at_least_once.returns({'ok' => true }) subject.new.save(fake_request) end describe "when the document exists" do before do @doc = CouchRest::Document.new(:_id => fake_request.key, :facts => fake_request.instance.values) @mock_db.expects(:get).with(fake_request.key).returns(@doc) end it "saves the document" do @doc.expects(:save) subject.new.save(fake_request) end end describe "when the document does not exist" do before do @mock_db.expects(:get). with(fake_request.key). raises(RestClient::ResourceNotFound) end it "saves the document" do @mock_db.expects(:save_doc) subject.new.save(fake_request) end end end def fake_request(options={}) facts = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml', 'test.local.yaml')) Struct.new(:instance, :key, :options).new(facts, facts.name, options) end private :fake_request end end diff --git a/spec/unit/indirector/ldap_spec.rb b/spec/unit/indirector/ldap_spec.rb index d4c9ddcff..2b40325de 100755 --- a/spec/unit/indirector/ldap_spec.rb +++ b/spec/unit/indirector/ldap_spec.rb @@ -1,137 +1,137 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/indirector/ldap' describe Puppet::Indirector::Ldap do before do @indirection = stub 'indirection', :name => :testing Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) module Testing; end @ldap_class = class Testing::MyLdap < Puppet::Indirector::Ldap self end @connection = mock 'ldap' @searcher = @ldap_class.new end describe "when searching ldap" do before do # Stub everything, and we can selectively replace with an expect as # we need to for testing. @searcher.stubs(:connection).returns(@connection) @searcher.stubs(:search_filter).returns(:filter) @searcher.stubs(:search_base).returns(:base) @searcher.stubs(:process) @request = stub 'request', :key => "yay" end it "should call the ldapsearch method with the search filter" do @searcher.expects(:search_filter).with("yay").returns("yay's filter") @searcher.expects(:ldapsearch).with("yay's filter") @searcher.find @request end it "should fail if no block is passed to the ldapsearch method" do proc { @searcher.ldapsearch("blah") }.should raise_error(ArgumentError) end it "should use the results of the ldapbase method as the ldap search base" do @searcher.stubs(:search_base).returns("mybase") @connection.expects(:search).with do |*args| args[0].should == "mybase" true end @searcher.find @request end it "should default to the value of the :search_base setting as the result of the ldapbase method" do Puppet.expects(:[]).with(:ldapbase).returns("myldapbase") searcher = @ldap_class.new searcher.search_base.should == "myldapbase" end it "should use the results of the :search_attributes method as the list of attributes to return" do @searcher.stubs(:search_attributes).returns(:myattrs) @connection.expects(:search).with do |*args| args[3].should == :myattrs true end @searcher.find @request end it "should use depth 2 when searching" do @connection.expects(:search).with do |*args| args[1].should == 2 true end @searcher.find @request end it "should call process() on the first found entry" do @connection.expects(:search).yields("myresult") @searcher.expects(:process).with("myresult") @searcher.find @request end it "should reconnect and retry the search if there is a failure" do run = false @connection.stubs(:search).with do |*args| if run true else run = true raise "failed" end end.yields("myresult") @searcher.expects(:process).with("myresult") @searcher.find @request end it "should not reconnect on failure more than once" do count = 0 @connection.stubs(:search).with do |*args| count += 1 raise ArgumentError, "yay" end proc { @searcher.find(@request) }.should raise_error(Puppet::Error) count.should == 2 end it "should return true if an entry is found" do @connection.expects(:search).yields("result") @searcher.ldapsearch("whatever") { |r| }.should be_true end end - describe "when connecting to ldap", :if => Puppet.features.ldap?, :'fails_on_ruby_1.9.2' => true do + describe "when connecting to ldap", :if => Puppet.features.ldap? do it "should create and start a Util::Ldap::Connection instance" do conn = mock 'connection', :connection => "myconn", :start => nil Puppet::Util::Ldap::Connection.expects(:instance).returns conn @searcher.connection.should == "myconn" end it "should only create the ldap connection when asked for it the first time" do conn = mock 'connection', :connection => "myconn", :start => nil Puppet::Util::Ldap::Connection.expects(:instance).returns conn @searcher.connection end it "should cache the connection" do conn = mock 'connection', :connection => "myconn", :start => nil Puppet::Util::Ldap::Connection.expects(:instance).returns conn @searcher.connection.should equal(@searcher.connection) end end describe "when reconnecting to ldap", :if => (Puppet.features.root? and Facter.value("hostname") == "culain") do it "should reconnect to ldap when connections are lost" end end diff --git a/spec/unit/indirector/report/yaml_spec.rb b/spec/unit/indirector/report/yaml_spec.rb index 557795f21..72bff8261 100755 --- a/spec/unit/indirector/report/yaml_spec.rb +++ b/spec/unit/indirector/report/yaml_spec.rb @@ -1,37 +1,28 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/transaction/report' require 'puppet/indirector/report/yaml' describe Puppet::Transaction::Report::Yaml do it "should be a subclass of the Yaml terminus" do Puppet::Transaction::Report::Yaml.superclass.should equal(Puppet::Indirector::Yaml) end it "should have documentation" do Puppet::Transaction::Report::Yaml.doc.should_not be_nil end it "should be registered with the report indirection" do indirection = Puppet::Indirector::Indirection.instance(:report) Puppet::Transaction::Report::Yaml.indirection.should equal(indirection) end it "should have its name set to :yaml" do Puppet::Transaction::Report::Yaml.name.should == :yaml end - it "should inconditionnally save/load from the --lastrunreport setting", :'fails_on_ruby_1.9.2' => true do - indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil - Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(indirection) - store_class = Class.new(Puppet::Transaction::Report::Yaml) do - def self.to_s - "MyYaml::MyType" - end - end - store = store_class.new - - store.path(:me).should == Puppet[:lastrunreport] + it "should unconditionally save/load from the --lastrunreport setting" do + subject.path(:me).should == Puppet[:lastrunreport] end end diff --git a/spec/unit/indirector/resource/ral_spec.rb b/spec/unit/indirector/resource/ral_spec.rb index 2a3fec0d3..0205db52e 100755 --- a/spec/unit/indirector/resource/ral_spec.rb +++ b/spec/unit/indirector/resource/ral_spec.rb @@ -1,130 +1,130 @@ #!/usr/bin/env rspec require 'spec_helper' describe "Puppet::Resource::Ral" do describe "find" do before do @request = stub 'request', :key => "user/root" end it "should find an existing instance" do my_resource = stub "my user resource" wrong_instance = stub "wrong user", :name => "bob" my_instance = stub "my user", :name => "root", :to_resource => my_resource require 'puppet/type/user' Puppet::Type::User.expects(:instances).returns([ wrong_instance, my_instance, wrong_instance ]) Puppet::Resource::Ral.new.find(@request).should == my_resource end - it "if there is no instance, it should create one", :'fails_on_ruby_1.9.2' => true do + it "if there is no instance, it should create one" do wrong_instance = stub "wrong user", :name => "bob" require 'puppet/type/user' Puppet::Type::User.expects(:instances).returns([ wrong_instance, wrong_instance ]) result = Puppet::Resource::Ral.new.find(@request) result.should be_is_a(Puppet::Resource) result.title.should == "root" end end describe "search" do before do @request = stub 'request', :key => "user/", :options => {} end it "should convert ral resources into regular resources" do my_resource = stub "my user resource" my_instance = stub "my user", :name => "root", :to_resource => my_resource require 'puppet/type/user' Puppet::Type::User.expects(:instances).returns([ my_instance ]) Puppet::Resource::Ral.new.search(@request).should == [my_resource] end it "should filter results by name if there's a name in the key" do my_resource = stub "my user resource" my_resource.stubs(:to_resource).returns(my_resource) my_resource.stubs(:[]).with(:name).returns("root") wrong_resource = stub "wrong resource" wrong_resource.stubs(:to_resource).returns(wrong_resource) wrong_resource.stubs(:[]).with(:name).returns("bad") my_instance = stub "my user", :to_resource => my_resource wrong_instance = stub "wrong user", :to_resource => wrong_resource @request = stub 'request', :key => "user/root", :options => {} require 'puppet/type/user' Puppet::Type::User.expects(:instances).returns([ my_instance, wrong_instance ]) Puppet::Resource::Ral.new.search(@request).should == [my_resource] end it "should filter results by query parameters" do wrong_resource = stub "my user resource" wrong_resource.stubs(:to_resource).returns(wrong_resource) wrong_resource.stubs(:[]).with(:name).returns("root") my_resource = stub "wrong resource" my_resource.stubs(:to_resource).returns(my_resource) my_resource.stubs(:[]).with(:name).returns("bob") my_instance = stub "my user", :to_resource => my_resource wrong_instance = stub "wrong user", :to_resource => wrong_resource @request = stub 'request', :key => "user/", :options => {:name => "bob"} require 'puppet/type/user' Puppet::Type::User.expects(:instances).returns([ my_instance, wrong_instance ]) Puppet::Resource::Ral.new.search(@request).should == [my_resource] end it "should return sorted results" do a_resource = stub "alice resource" a_resource.stubs(:to_resource).returns(a_resource) a_resource.stubs(:title).returns("alice") b_resource = stub "bob resource" b_resource.stubs(:to_resource).returns(b_resource) b_resource.stubs(:title).returns("bob") a_instance = stub "alice user", :to_resource => a_resource b_instance = stub "bob user", :to_resource => b_resource @request = stub 'request', :key => "user/", :options => {} require 'puppet/type/user' Puppet::Type::User.expects(:instances).returns([ b_instance, a_instance ]) Puppet::Resource::Ral.new.search(@request).should == [a_resource, b_resource] end end describe "save" do before do @rebuilt_res = stub 'rebuilt instance' @ral_res = stub 'ral resource', :to_resource => @rebuilt_res @instance = stub 'instance', :to_ral => @ral_res @request = stub 'request', :key => "user/", :instance => @instance @catalog = stub 'catalog' @report = stub 'report' @transaction = stub 'transaction', :report => @report Puppet::Resource::Catalog.stubs(:new).returns(@catalog) @catalog.stubs(:apply).returns(@transaction) @catalog.stubs(:add_resource) end it "should apply a new catalog with a ral object in it" do Puppet::Resource::Catalog.expects(:new).returns(@catalog) @catalog.expects(:add_resource).with(@ral_res) @catalog.expects(:apply).returns(@transaction) Puppet::Resource::Ral.new.save(@request).should end it "should return a regular resource that used to be the ral resource" do Puppet::Resource::Ral.new.save(@request).should == [@rebuilt_res, @report] end end end diff --git a/spec/unit/indirector/terminus_spec.rb b/spec/unit/indirector/terminus_spec.rb index ccd6fd237..ffd89a20f 100755 --- a/spec/unit/indirector/terminus_spec.rb +++ b/spec/unit/indirector/terminus_spec.rb @@ -1,250 +1,217 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/defaults' require 'puppet/indirector' require 'puppet/indirector/memory' -describe Puppet::Indirector::Terminus, :'fails_on_ruby_1.9.2' => true do - before :each do - Puppet::Indirector::Terminus.stubs(:register_terminus_class) - @indirection = stub 'indirection', :name => :my_stuff, :register_terminus_type => nil - Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection) - @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do - def self.to_s - "Testing::Abstract" - end - end - @terminus_class = Class.new(@abstract_terminus) do - def self.to_s - "MyStuff::TermType" - end +describe Puppet::Indirector::Terminus do + before :all do + class Puppet::AbstractConcept + extend Puppet::Indirector + indirects :abstract_concept end - @terminus = @terminus_class.new - end - - describe Puppet::Indirector::Terminus do - it "should provide a method for setting terminus class documentation" do - @terminus_class.should respond_to(:desc) - end - - it "should support a class-level name attribute" do - @terminus_class.should respond_to(:name) + class Puppet::AbstractConcept::Freedom < Puppet::Indirector::Code end + end - it "should support a class-level indirection attribute" do - @terminus_class.should respond_to(:indirection) - end + after :all do + # Remove the class, unlinking it from the rest of the system. + Puppet.send(:remove_const, :AbstractConcept) + end - it "should support a class-level terminus-type attribute" do - @terminus_class.should respond_to(:terminus_type) - end + let :terminus_class do Puppet::AbstractConcept::Freedom end + let :terminus do terminus_class.new end + let :indirection do Puppet::AbstractConcept.indirection end - it "should support a class-level model attribute" do - @terminus_class.should respond_to(:model) - end + it "should provide a method for setting terminus class documentation" do + terminus_class.should respond_to(:desc) + end - it "should accept indirection instances as its indirection" do - indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil - proc { @terminus_class.indirection = indirection }.should_not raise_error - @terminus_class.indirection.should equal(indirection) - end + it "should support a class-level name attribute" do + terminus_class.should respond_to(:name) + end - it "should look up indirection instances when only a name has been provided" do - indirection = mock 'indirection' - Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection) - @terminus_class.indirection = :myind - @terminus_class.indirection.should equal(indirection) - end + it "should support a class-level indirection attribute" do + terminus_class.should respond_to(:indirection) + end - it "should fail when provided a name that does not resolve to an indirection" do - Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil) - proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError) + it "should support a class-level terminus-type attribute" do + terminus_class.should respond_to(:terminus_type) + end - # It shouldn't overwrite our existing one (or, more normally, it shouldn't set - # anything). - @terminus_class.indirection.should equal(@indirection) - end + it "should support a class-level model attribute" do + terminus_class.should respond_to(:model) end - describe Puppet::Indirector::Terminus, " when creating terminus classes" do - it "should associate the subclass with an indirection based on the subclass constant" do - @terminus.indirection.should equal(@indirection) - end + it "should accept indirection instances as its indirection" do + # The test is that this shouldn't raise, and should preserve the object + # instance exactly, hence "equal", not just "==". + terminus_class.indirection = indirection + terminus_class.indirection.should equal indirection + end - it "should set the subclass's type to the abstract terminus name" do - @terminus.terminus_type.should == :abstract - end + it "should look up indirection instances when only a name has been provided" do + terminus_class.indirection = :abstract_concept + terminus_class.indirection.should equal indirection + end - it "should set the subclass's name to the indirection name" do - @terminus.name.should == :term_type - end + it "should fail when provided a name that does not resolve to an indirection" do + expect { terminus_class.indirection = :exploding_whales }. + should raise_error(ArgumentError) - it "should set the subclass's model to the indirection model" do - @indirection.expects(:model).returns :yay - @terminus.model.should == :yay - end + # We should still have the default indirection. + terminus_class.indirection.should equal indirection end - describe Puppet::Indirector::Terminus, " when a terminus instance" do - + describe "when a terminus instance" do it "should return the class's name as its name" do - @terminus.name.should == :term_type + terminus.name.should == :freedom end it "should return the class's indirection as its indirection" do - @terminus.indirection.should equal(@indirection) + terminus.indirection.should equal indirection end it "should set the instances's type to the abstract terminus type's name" do - @terminus.terminus_type.should == :abstract + terminus.terminus_type.should == :code end it "should set the instances's model to the indirection's model" do - @indirection.expects(:model).returns :yay - @terminus.model.should == :yay + terminus.model.should equal indirection.model end end -end -# LAK: This could reasonably be in the Indirection instances, too. It doesn't make -# a whole heckuva lot of difference, except that with the instance loading in -# the Terminus base class, we have to have a check to see if we're already -# instance-loading a given terminus class type. -describe Puppet::Indirector::Terminus, " when managing terminus classes" do - it "should provide a method for registering terminus classes" do - Puppet::Indirector::Terminus.should respond_to(:register_terminus_class) - end + describe "when managing terminus classes" do + it "should provide a method for registering terminus classes" do + Puppet::Indirector::Terminus.should respond_to(:register_terminus_class) + end - it "should provide a method for returning terminus classes by name and type" do - terminus = stub 'terminus_type', :name => :abstract, :indirection_name => :whatever - Puppet::Indirector::Terminus.register_terminus_class(terminus) - Puppet::Indirector::Terminus.terminus_class(:whatever, :abstract).should equal(terminus) - end + it "should provide a method for returning terminus classes by name and type" do + terminus = stub 'terminus_type', :name => :abstract, :indirection_name => :whatever + Puppet::Indirector::Terminus.register_terminus_class(terminus) + Puppet::Indirector::Terminus.terminus_class(:whatever, :abstract).should equal(terminus) + end - it "should set up autoloading for any terminus class types requested" do - Puppet::Indirector::Terminus.expects(:instance_load).with(:test2, "puppet/indirector/test2") - Puppet::Indirector::Terminus.terminus_class(:test2, :whatever) - end + it "should set up autoloading for any terminus class types requested" do + Puppet::Indirector::Terminus.expects(:instance_load).with(:test2, "puppet/indirector/test2") + Puppet::Indirector::Terminus.terminus_class(:test2, :whatever) + end - it "should load terminus classes that are not found" do - # Set up instance loading; it would normally happen automatically - Puppet::Indirector::Terminus.instance_load :test1, "puppet/indirector/test1" + it "should load terminus classes that are not found" do + # Set up instance loading; it would normally happen automatically + Puppet::Indirector::Terminus.instance_load :test1, "puppet/indirector/test1" - Puppet::Indirector::Terminus.instance_loader(:test1).expects(:load).with(:yay) - Puppet::Indirector::Terminus.terminus_class(:test1, :yay) - end + Puppet::Indirector::Terminus.instance_loader(:test1).expects(:load).with(:yay) + Puppet::Indirector::Terminus.terminus_class(:test1, :yay) + end - it "should fail when no indirection can be found", :'fails_on_ruby_1.9.2' => true do - Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(nil) + it "should fail when no indirection can be found" do + Puppet::Indirector::Indirection.expects(:instance).with(:abstract_concept).returns(nil) + expect { + class Puppet::AbstractConcept::Physics < Puppet::Indirector::Code + end + }.should raise_error(ArgumentError) + end - @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do - def self.to_s - "Abstract" + it "should register the terminus class with the terminus base class" do + Puppet::Indirector::Terminus.expects(:register_terminus_class).with do |type| + type.indirection_name == :abstract_concept and type.name == :intellect end - end - proc { - @terminus = Class.new(@abstract_terminus) do - def self.to_s - "MyIndirection::TestType" + + begin + class Puppet::AbstractConcept::Intellect < Puppet::Indirector::Code end + ensure + Puppet::AbstractConcept.send(:remove_const, :Intellect) rescue nil end - }.should raise_error(ArgumentError) + end end - it "should register the terminus class with the terminus base class", :'fails_on_ruby_1.9.2' => true do - Puppet::Indirector::Terminus.expects(:register_terminus_class).with do |type| - type.indirection_name == :my_indirection and type.name == :test_terminus + describe "when parsing class constants for indirection and terminus names" do + before :each do + Puppet::Indirector::Terminus.stubs(:register_terminus_class) end - @indirection = stub 'indirection', :name => :my_indirection, :register_terminus_type => nil - Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(@indirection) - @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do - def self.to_s - "Abstract" - end + let :subclass do + subclass = mock 'subclass' + subclass.stubs(:to_s).returns("TestInd::OneTwo") + subclass.stubs(:mark_as_abstract_terminus) + subclass end - @terminus = Class.new(@abstract_terminus) do - def self.to_s - "MyIndirection::TestTerminus" - end + it "should fail when anonymous classes are used" do + expect { Puppet::Indirector::Terminus.inherited(Class.new) }. + should raise_error(Puppet::DevError) end - end -end -describe Puppet::Indirector::Terminus, " when parsing class constants for indirection and terminus names" do - before do - @subclass = mock 'subclass' - @subclass.stubs(:to_s).returns("TestInd::OneTwo") - @subclass.stubs(:mark_as_abstract_terminus) - Puppet::Indirector::Terminus.stubs(:register_terminus_class) - end + it "should use the last term in the constant for the terminus class name" do + subclass.expects(:name=).with(:one_two) + subclass.stubs(:indirection=) + Puppet::Indirector::Terminus.inherited(subclass) + end - it "should fail when anonymous classes are used" do - proc { Puppet::Indirector::Terminus.inherited(Class.new) }.should raise_error(Puppet::DevError) - end + it "should convert the terminus name to a downcased symbol" do + subclass.expects(:name=).with(:one_two) + subclass.stubs(:indirection=) + Puppet::Indirector::Terminus.inherited(subclass) + end - it "should use the last term in the constant for the terminus class name" do - @subclass.expects(:name=).with(:one_two) - @subclass.stubs(:indirection=) - Puppet::Indirector::Terminus.inherited(@subclass) - end + it "should use the second to last term in the constant for the indirection name" do + subclass.expects(:indirection=).with(:test_ind) + subclass.stubs(:name=) + subclass.stubs(:terminus_type=) + Puppet::Indirector::Memory.inherited(subclass) + end - it "should convert the terminus name to a downcased symbol" do - @subclass.expects(:name=).with(:one_two) - @subclass.stubs(:indirection=) - Puppet::Indirector::Terminus.inherited(@subclass) - end + it "should convert the indirection name to a downcased symbol" do + subclass.expects(:indirection=).with(:test_ind) + subclass.stubs(:name=) + subclass.stubs(:terminus_type=) + Puppet::Indirector::Memory.inherited(subclass) + end - it "should use the second to last term in the constant for the indirection name" do - @subclass.expects(:indirection=).with(:test_ind) - @subclass.stubs(:name=) - @subclass.stubs(:terminus_type=) - Puppet::Indirector::Memory.inherited(@subclass) - end + it "should convert camel case to lower case with underscores as word separators" do + subclass.expects(:name=).with(:one_two) + subclass.stubs(:indirection=) - it "should convert the indirection name to a downcased symbol" do - @subclass.expects(:indirection=).with(:test_ind) - @subclass.stubs(:name=) - @subclass.stubs(:terminus_type=) - Puppet::Indirector::Memory.inherited(@subclass) + Puppet::Indirector::Terminus.inherited(subclass) + end end - it "should convert camel case to lower case with underscores as word separators" do - @subclass.expects(:name=).with(:one_two) - @subclass.stubs(:indirection=) - - Puppet::Indirector::Terminus.inherited(@subclass) - end -end + describe "when creating terminus class types" do + before :all do + Puppet::Indirector::Terminus.stubs(:register_terminus_class) -describe Puppet::Indirector::Terminus, " when creating terminus class types", :'fails_on_ruby_1.9.2' => true do - before do - Puppet::Indirector::Terminus.stubs(:register_terminus_class) - @subclass = Class.new(Puppet::Indirector::Terminus) do - def self.to_s - "Puppet::Indirector::Terminus::MyTermType" + class Puppet::Indirector::Terminus::TestTerminusType < Puppet::Indirector::Terminus end end - end - it "should set the name of the abstract subclass to be its class constant" do - @subclass.name.should equal(:my_term_type) - end + after :all do + Puppet::Indirector::Terminus.send(:remove_const, :TestTerminusType) + end - it "should mark abstract terminus types as such" do - @subclass.should be_abstract_terminus - end + let :subclass do + Puppet::Indirector::Terminus::TestTerminusType + end + + it "should set the name of the abstract subclass to be its class constant" do + subclass.name.should == :test_terminus_type + end + + it "should mark abstract terminus types as such" do + subclass.should be_abstract_terminus + end - it "should not allow instances of abstract subclasses to be created" do - proc { @subclass.new }.should raise_error(Puppet::DevError) + it "should not allow instances of abstract subclasses to be created" do + expect { subclass.new }.should raise_error(Puppet::DevError) + end end -end -describe Puppet::Indirector::Terminus, " when listing terminus classes" do - it "should list the terminus files available to load" do - Puppet::Util::Autoload.any_instance.stubs(:files_to_load).returns ["/foo/bar/baz", "/max/runs/marathon"] - Puppet::Indirector::Terminus.terminus_classes('my_stuff').should == [:baz, :marathon] + describe "when listing terminus classes" do + it "should list the terminus files available to load" do + Puppet::Util::Autoload.any_instance.stubs(:files_to_load).returns ["/foo/bar/baz", "/max/runs/marathon"] + Puppet::Indirector::Terminus.terminus_classes('my_stuff').should == [:baz, :marathon] + end end end diff --git a/spec/unit/indirector/yaml_spec.rb b/spec/unit/indirector/yaml_spec.rb index 3f3ca1284..7fdfa7e3b 100755 --- a/spec/unit/indirector/yaml_spec.rb +++ b/spec/unit/indirector/yaml_spec.rb @@ -1,190 +1,183 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/indirector/yaml' describe Puppet::Indirector::Yaml, " when choosing file location" do before :all do @indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil Puppet::Indirector::Indirection.expects(:instance).with(:my_yaml).returns(@indirection) module MyYaml; end @store_class = class MyYaml::MyType < Puppet::Indirector::Yaml self end end before :each do @store = @store_class.new @subject = Object.new @subject.singleton_class.send(:attr_accessor, :name) @subject.name = :me @dir = "/what/ever" Puppet.settings.stubs(:value).returns("fakesettingdata") Puppet.settings.stubs(:value).with(:clientyamldir).returns(@dir) Puppet.run_mode.stubs(:master?).returns false @request = stub 'request', :key => :me, :instance => @subject end describe Puppet::Indirector::Yaml, " when choosing file location" do it "should use the server_datadir if the run_mode is master" do Puppet.run_mode.expects(:master?).returns true Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir" @store.path(:me).should =~ %r{^/server/yaml/dir} end it "should use the client yamldir if the run_mode is not master" do Puppet.run_mode.expects(:master?).returns false Puppet.settings.expects(:value).with(:clientyamldir).returns "/client/yaml/dir" @store.path(:me).should =~ %r{^/client/yaml/dir} end it "should use the extension if one is specified" do Puppet.run_mode.expects(:master?).returns true Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir" @store.path(:me,'.farfignewton').should =~ %r{\.farfignewton$} end it "should assume an extension of .yaml if none is specified" do Puppet.run_mode.expects(:master?).returns true Puppet.settings.expects(:value).with(:yamldir).returns "/server/yaml/dir" @store.path(:me).should =~ %r{\.yaml$} end it "should store all files in a single file root set in the Puppet defaults" do @store.path(:me).should =~ %r{^#{@dir}} end it "should use the terminus name for choosing the subdirectory" do @store.path(:me).should =~ %r{^#{@dir}/my_yaml} end it "should use the object's name to determine the file name" do @store.path(:me).should =~ %r{me.yaml$} end ['../foo', '..\\foo', './../foo', '.\\..\\foo', '/foo', '//foo', '\\foo', '\\\\goo', "test\0/../bar", "test\0\\..\\bar", "..\\/bar", "/tmp/bar", "/tmp\\bar", "tmp\\bar", " / bar", " /../ bar", " \\..\\ bar", "c:\\foo", "c:/foo", "\\\\?\\UNC\\bar", "\\\\foo\\bar", "\\\\?\\c:\\foo", "//?/UNC/bar", "//foo/bar", "//?/c:/foo", ].each do |input| it "should resist directory traversal attacks (#{input.inspect})" do expect { @store.path(input) }.to raise_error end end end describe Puppet::Indirector::Yaml, " when storing objects as YAML" do it "should only store objects that respond to :name" do @request.stubs(:instance).returns Object.new proc { @store.save(@request) }.should raise_error(ArgumentError) end it "should convert Ruby objects to YAML and write them to disk using a write lock" do yaml = @subject.to_yaml file = mock 'file' path = @store.send(:path, @subject.name) FileTest.expects(:exist?).with(File.dirname(path)).returns(true) - @store.expects(:writelock).with(path, 0660).yields(file) + Puppet::Util.expects(:replace_file).with(path, 0660).yields(file) file.expects(:print).with(yaml) @store.save(@request) end it "should create the indirection subdirectory if it does not exist" do yaml = @subject.to_yaml file = mock 'file' path = @store.send(:path, @subject.name) dir = File.dirname(path) FileTest.expects(:exist?).with(dir).returns(false) Dir.expects(:mkdir).with(dir) - @store.expects(:writelock).yields(file) + Puppet::Util.expects(:replace_file).yields(file) file.expects(:print).with(yaml) @store.save(@request) end end - describe Puppet::Indirector::Yaml, " when retrieving YAML" do - it "should read YAML in from disk using a read lock and convert it to Ruby objects" do + describe "when retrieving YAML" do + it "should read YAML in from disk and convert it to Ruby objects" do path = @store.send(:path, @subject.name) - yaml = @subject.to_yaml - FileTest.expects(:exist?).with(path).returns(true) - fh = mock 'filehandle' - @store.expects(:readlock).with(path).yields fh - fh.expects(:read).returns yaml + FileTest.expects(:exist?).with(path).returns true + File.expects(:read).with(path).returns yaml @store.find(@request).instance_variable_get("@name").should == :me end it "should fail coherently when the stored YAML is invalid" do path = @store.send(:path, @subject.name) FileTest.expects(:exist?).with(path).returns(true) # Something that will fail in yaml - yaml = "--- !ruby/object:Hash" - - fh = mock 'filehandle' - @store.expects(:readlock).yields fh - fh.expects(:read).returns yaml + File.expects(:read).returns "--- foo:\n 1,2,3\nargh" - proc { @store.find(@request) }.should raise_error(Puppet::Error) + expect { @store.find(@request) }.should raise_error(Puppet::Error) end end describe Puppet::Indirector::Yaml, " when searching" do it "should return an array of fact instances with one instance for each file when globbing *" do @request = stub 'request', :key => "*", :instance => @subject @one = mock 'one' @two = mock 'two' @store.expects(:path).with(@request.key,'').returns :glob Dir.expects(:glob).with(:glob).returns(%w{one.yaml two.yaml}) YAML.expects(:load_file).with("one.yaml").returns @one; YAML.expects(:load_file).with("two.yaml").returns @two; @store.search(@request).should == [@one, @two] end it "should return an array containing a single instance of fact when globbing 'one*'" do @request = stub 'request', :key => "one*", :instance => @subject @one = mock 'one' @store.expects(:path).with(@request.key,'').returns :glob Dir.expects(:glob).with(:glob).returns(%w{one.yaml}) YAML.expects(:load_file).with("one.yaml").returns @one; @store.search(@request).should == [@one] end it "should return an empty array when the glob doesn't match anything" do @request = stub 'request', :key => "f*ilglobcanfail*", :instance => @subject @store.expects(:path).with(@request.key,'').returns :glob Dir.expects(:glob).with(:glob).returns [] @store.search(@request).should == [] end describe Puppet::Indirector::Yaml, " when destroying" do it "should unlink the right yaml file if it exists" do path = File.join("/what/ever", @store.class.indirection_name.to_s, @request.key.to_s + ".yaml") File.expects(:exists?).with(path).returns true File.expects(:unlink).with(path) @store.destroy(@request) end it "should not unlink the yaml file if it does not exists" do path = File.join("/what/ever", @store.class.indirection_name.to_s, @request.key.to_s + ".yaml") File.expects(:exists?).with(path).returns false File.expects(:unlink).with(path).never @store.destroy(@request) end end end end diff --git a/spec/unit/interface_spec.rb b/spec/unit/interface_spec.rb index 4ff71ac3d..1621b9ad8 100755 --- a/spec/unit/interface_spec.rb +++ b/spec/unit/interface_spec.rb @@ -1,233 +1,233 @@ require 'spec_helper' require 'puppet/face' require 'puppet/interface' describe Puppet::Interface do subject { Puppet::Interface } before :each do @faces = Puppet::Interface::FaceCollection. instance_variable_get("@faces").dup @dq = $".dup $".delete_if do |path| path =~ %r{/face/.*\.rb$} end Puppet::Interface::FaceCollection.instance_variable_get("@faces").clear end after :each do Puppet::Interface::FaceCollection.instance_variable_set("@faces", @faces) $".clear ; @dq.each do |item| $" << item end end describe "#[]" do it "should fail when no version is requested" do expect { subject[:huzzah] }.should raise_error ArgumentError end it "should raise an exception when the requested version is unavailable" do expect { subject[:huzzah, '17.0.0'] }.should raise_error, Puppet::Error end it "should raise an exception when the requested face doesn't exist" do expect { subject[:burrble_toot, :current] }.should raise_error, Puppet::Error end describe "version matching" do { '1' => '1.1.1', '1.0' => '1.0.1', '1.0.1' => '1.0.1', '1.1' => '1.1.1', '1.1.1' => '1.1.1' }.each do |input, expect| it "should match #{input.inspect} to #{expect.inspect}" do face = subject[:version_matching, input] face.should be face.version.should == expect end end %w{1.0.2 1.2}.each do |input| it "should not match #{input.inspect} to any version" do expect { subject[:version_matching, input] }. to raise_error Puppet::Error, /Could not find version/ end end end end describe "#define" do it "should register the face" do face = subject.define(:face_test_register, '0.0.1') face.should == subject[:face_test_register, '0.0.1'] end it "should load actions" do subject.any_instance.expects(:load_actions) subject.define(:face_test_load_actions, '0.0.1') end it "should require a version number" do expect { subject.define(:no_version) }.to raise_error ArgumentError end it "should support summary builder and accessor methods" do subject.new(:foo, '1.0.0').should respond_to(:summary).with(0).arguments subject.new(:foo, '1.0.0').should respond_to(:summary=).with(1).arguments end # Required documentation methods... { :summary => "summary", :description => "This is the description of the stuff\n\nWhee", :examples => "This is my example", :short_description => "This is my custom short description", :notes => "These are my notes...", :author => "This is my authorship data", }.each do |attr, value| it "should support #{attr} in the builder" do face = subject.new(:builder, '1.0.0') do self.send(attr, value) end face.send(attr).should == value end end end describe "#initialize" do it "should require a version number" do expect { subject.new(:no_version) }.to raise_error ArgumentError end it "should require a valid version number" do expect { subject.new(:bad_version, 'Rasins') }. should raise_error ArgumentError end - it "should instance-eval any provided block", :'fails_on_ruby_1.9.2' => true do + it "should instance-eval any provided block" do face = subject.new(:face_test_block, '0.0.1') do action(:something) do - when_invoked { "foo" } + when_invoked {|_| "foo" } end end face.something.should == "foo" end end it "should have a name" do subject.new(:me, '0.0.1').name.should == :me end it "should stringify with its own name" do subject.new(:me, '0.0.1').to_s.should =~ /\bme\b/ end # Why? it "should create a class-level autoloader" do subject.autoloader.should be_instance_of(Puppet::Util::Autoload) end it "should try to require faces that are not known" do subject::FaceCollection.expects(:load_face).with(:foo, :current) subject::FaceCollection.expects(:load_face).with(:foo, '0.0.1') expect { subject[:foo, '0.0.1'] }.to raise_error Puppet::Error end it_should_behave_like "things that declare options" do def add_options_to(&block) subject.new(:with_options, '0.0.1', &block) end end - describe "with face-level options", :'fails_on_ruby_1.9.2' => true do + describe "with face-level options" do it "should not return any action-level options" do face = subject.new(:with_options, '0.0.1') do option "--foo" option "--bar" action :baz do - when_invoked { true } + when_invoked {|_| true } option "--quux" end end face.options.should =~ [:foo, :bar] end it "should fail when a face option duplicates an action option" do expect { subject.new(:action_level_options, '0.0.1') do action :bar do - when_invoked { true } + when_invoked {|_| true } option "--foo" end option "--foo" end }.should raise_error ArgumentError, /Option foo conflicts with existing option foo on/i end it "should work when two actions have the same option" do face = subject.new(:with_options, '0.0.1') do - action :foo do when_invoked { true } ; option "--quux" end - action :bar do when_invoked { true } ; option "--quux" end + action :foo do when_invoked {|_| true } ; option "--quux" end + action :bar do when_invoked {|_| true } ; option "--quux" end end face.get_action(:foo).options.should =~ [:quux] face.get_action(:bar).options.should =~ [:quux] end it "should only list options and not aliases" do face = subject.new(:face_options, '0.0.1') do option "--bar", "-b", "--foo-bar" end face.options.should =~ [:bar] end end describe "with inherited options" do let :parent do parent = Class.new(subject) parent.option("--inherited") - parent.action(:parent_action) do when_invoked { true } end + parent.action(:parent_action) do when_invoked {|_| true } end parent end let :face do face = parent.new(:example, '0.2.1') face.option("--local") - face.action(:face_action) do when_invoked { true } end + face.action(:face_action) do when_invoked {|_| true } end face end - describe "#options", :'fails_on_ruby_1.9.2' => true do + describe "#options" do it "should list inherited options" do face.options.should =~ [:inherited, :local] end it "should see all options on face actions" do face.get_action(:face_action).options.should =~ [:inherited, :local] end it "should see all options on inherited actions accessed on the subclass" do face.get_action(:parent_action).options.should =~ [:inherited, :local] end it "should not see subclass actions on the parent class" do parent.options.should =~ [:inherited] end it "should not see subclass actions on actions accessed on the parent class" do parent.get_action(:parent_action).options.should =~ [:inherited] end end - describe "#get_option", :'fails_on_ruby_1.9.2' => true do + describe "#get_option" do it "should return an inherited option object" do face.get_option(:inherited).should be_an_instance_of subject::Option end end end it_should_behave_like "documentation on faces" do subject do Puppet::Interface.new(:face_documentation, '0.0.1') end end end diff --git a/spec/unit/network/http/mongrel/rest_spec.rb b/spec/unit/network/http/mongrel/rest_spec.rb index d87596f77..51ce3fccb 100755 --- a/spec/unit/network/http/mongrel/rest_spec.rb +++ b/spec/unit/network/http/mongrel/rest_spec.rb @@ -1,276 +1,276 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/network/http' -describe "Puppet::Network::HTTP::MongrelREST", :if => Puppet.features.mongrel?, :'fails_on_ruby_1.9.2' => true do +describe "Puppet::Network::HTTP::MongrelREST", :if => Puppet.features.mongrel? do before do require 'puppet/network/http/mongrel/rest' end it "should include the Puppet::Network::HTTP::Handler module" do Puppet::Network::HTTP::MongrelREST.ancestors.should be_include(Puppet::Network::HTTP::Handler) end describe "when initializing" do it "should call the Handler's initialization hook with its provided arguments as the server and handler" do Puppet::Network::HTTP::MongrelREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments") Puppet::Network::HTTP::MongrelREST.new(:server => "my", :handler => "arguments") end end describe "when receiving a request" do before do @params = {} @request = stub('mongrel http request', :params => @params) @head = stub('response head') @body = stub('response body', :write => true) @response = stub('mongrel http response') @response.stubs(:start).yields(@head, @body) @model_class = stub('indirected model class') @mongrel = stub('mongrel http server', :register => true) Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class) @handler = Puppet::Network::HTTP::MongrelREST.new(:server => @mongrel, :handler => :foo) end describe "and using the HTTP Handler interface" do it "should return the HTTP_ACCEPT parameter as the accept header" do @params.expects(:[]).with("HTTP_ACCEPT").returns "myaccept" @handler.accept_header(@request).should == "myaccept" end it "should return the Content-Type parameter as the Content-Type header" do @params.expects(:[]).with("HTTP_CONTENT_TYPE").returns "mycontent" @handler.content_type_header(@request).should == "mycontent" end it "should use the REQUEST_METHOD as the http method" do @params.expects(:[]).with(Mongrel::Const::REQUEST_METHOD).returns "mymethod" @handler.http_method(@request).should == "mymethod" end it "should return the request path as the path" do @params.expects(:[]).with(Mongrel::Const::REQUEST_PATH).returns "/foo/bar" @handler.path(@request).should == "/foo/bar" end it "should return the request body as the body" do @request.stubs(:body).returns StringIO.new("mybody") @handler.body(@request).should == "mybody" end it "should set the response's content-type header when setting the content type" do @header = mock 'header' @response.expects(:header).returns @header @header.expects(:[]=).with('Content-Type', "mytype") @handler.set_content_type(@response, "mytype") end it "should set the status and write the body when setting the response for a successful request" do head = mock 'head' body = mock 'body' @response.expects(:start).with(200).yields(head, body) body.expects(:write).with("mybody") @handler.set_response(@response, "mybody", 200) end describe "when the result is a File" do it "should use response send_file" do head = mock 'head' body = mock 'body' stat = stub 'stat', :size => 100 file = stub 'file', :stat => stat, :path => "/tmp/path" file.stubs(:is_a?).with(File).returns(true) @response.expects(:start).with(200).yields(head, body) @response.expects(:send_status).with(100) @response.expects(:send_header) @response.expects(:send_file).with("/tmp/path") @handler.set_response(@response, file, 200) end end it "should set the status and reason and write the body when setting the response for a successful request" do head = mock 'head' body = mock 'body' @response.expects(:start).with(400, false, "mybody").yields(head, body) body.expects(:write).with("mybody") @handler.set_response(@response, "mybody", 400) end end describe "and determining the request parameters" do before do @params = {'REQUEST_METHOD' => 'GET'} @request.stubs(:params).returns(@params) end it "should skip empty parameter values" do @params['QUERY_STRING'] = "&=" lambda { @handler.params(@request) }.should_not raise_error end it "should include the HTTP request parameters, with the keys as symbols" do @params['QUERY_STRING'] = 'foo=baz&bar=xyzzy' result = @handler.params(@request) result[:foo].should == "baz" result[:bar].should == "xyzzy" end it "should CGI-decode the HTTP parameters" do escaped = CGI.escape("foo bar") @params['QUERY_STRING'] = "foo=#{escaped}" result = @handler.params(@request) result[:foo].should == "foo bar" end it "should include parameters from the body of a POST request" do @params.merge!( 'QUERY_STRING' => nil, 'REQUEST_METHOD' => 'POST' ) body = StringIO.new('foo=bar&baz=qux') @request.stubs(:body).returns(body) @handler.params(@request).should include( :foo => 'bar', :baz => 'qux' ) end it "should convert the string 'true' to the boolean" do @params['QUERY_STRING'] = 'foo=true' result = @handler.params(@request) result[:foo].should be_true end it "should convert the string 'false' to the boolean" do @params['QUERY_STRING'] = 'foo=false' result = @handler.params(@request) result[:foo].should be_false end it "should convert integer arguments to Integers" do @params['QUERY_STRING'] = 'foo=15' result = @handler.params(@request) result[:foo].should == 15 end it "should convert floating point arguments to Floats" do @params['QUERY_STRING'] = 'foo=1.5' result = @handler.params(@request) result[:foo].should == 1.5 end it "should YAML-load and URI-decode values that are YAML-encoded" do escaping = CGI.escape(YAML.dump(%w{one two})) @params['QUERY_STRING'] = "foo=#{escaping}" result = @handler.params(@request) result[:foo].should == %w{one two} end it "should not allow the client to set the node via the query string" do @params['QUERY_STRING'] = "node=foo" @handler.params(@request)[:node].should be_nil end it "should not allow the client to set the IP address via the query string" do @params['QUERY_STRING'] = "ip=foo" @handler.params(@request)[:ip].should be_nil end it "should pass the client's ip address to model find" do @params['REMOTE_ADDR'] = "ipaddress" @handler.params(@request)[:ip].should == "ipaddress" end it "should pass the client's provided X-Forwared-For value as the ip" do @params["HTTP_X_FORWARDED_FOR"] = "ipaddress" @handler.params(@request)[:ip].should == "ipaddress" end it "should pass the client's provided X-Forwared-For first value as the ip" do @params["HTTP_X_FORWARDED_FOR"] = "ipproxy1,ipproxy2,ipaddress" @handler.params(@request)[:ip].should == "ipaddress" end it "should pass the client's provided X-Forwared-For value as the ip instead of the REMOTE_ADDR" do @params.merge!( "REMOTE_ADDR" => "remote_addr", "HTTP_X_FORWARDED_FOR" => "ipaddress" ) @handler.params(@request)[:ip].should == "ipaddress" end it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do Puppet.settings.stubs(:value).returns "eh" Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader" @params["myheader"] = "/CN=host.domain.com" @handler.params(@request) end it "should retrieve the hostname by matching the certificate parameter" do Puppet.settings.stubs(:value).returns "eh" Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader" @params["myheader"] = "/CN=host.domain.com" @handler.params(@request)[:node].should == "host.domain.com" end it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader" @params.merge!( "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com" ) @handler.params(@request) end it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader" @params.merge!( "myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com" ) @handler.params(@request)[:authenticated].should be_true end it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader" @params.merge!( "myheader" => "whatever", "certheader" => "/CN=host.domain.com" ) @handler.params(@request)[:authenticated].should be_false end it "should consider the host unauthenticated if no certificate information is present" do Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader" @params.merge!( "myheader" => nil, "certheader" => "SUCCESS" ) @handler.params(@request)[:authenticated].should be_false end it "should resolve the node name with an ip address look-up if no certificate is present" do Puppet.settings.stubs(:value).returns "eh" Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader" @params["myheader"] = nil @handler.expects(:resolve_node).returns("host.domain.com") @handler.params(@request)[:node].should == "host.domain.com" end end end end diff --git a/spec/unit/network/http/mongrel_spec.rb b/spec/unit/network/http/mongrel_spec.rb index 2e0ff04a0..b8e486d25 100755 --- a/spec/unit/network/http/mongrel_spec.rb +++ b/spec/unit/network/http/mongrel_spec.rb @@ -1,91 +1,91 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/network/http' -describe "Puppet::Network::HTTP::Mongrel", "after initializing", :if => Puppet.features.mongrel?, :'fails_on_ruby_1.9.2' => true do - it "should not be listening", :'fails_on_ruby_1.9.2' => true do +describe "Puppet::Network::HTTP::Mongrel", "after initializing", :if => Puppet.features.mongrel? do + it "should not be listening" do require 'puppet/network/http/mongrel' Puppet::Network::HTTP::Mongrel.new.should_not be_listening end end -describe "Puppet::Network::HTTP::Mongrel", "when turning on listening", :if => Puppet.features.mongrel?, :'fails_on_ruby_1.9.2' => true do +describe "Puppet::Network::HTTP::Mongrel", "when turning on listening", :if => Puppet.features.mongrel? do before do require 'puppet/network/http/mongrel' @server = Puppet::Network::HTTP::Mongrel.new @mock_mongrel = mock('mongrel') @mock_mongrel.stubs(:run) @mock_mongrel.stubs(:register) Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel) @listen_params = { :address => "127.0.0.1", :port => 31337 } end it "should fail if already listening" do @server.listen(@listen_params) Proc.new { @server.listen(@listen_params) }.should raise_error(RuntimeError) end it "should require a listening address to be specified" do Proc.new { @server.listen(@listen_params.delete_if {|k,v| :address == k})}.should raise_error(ArgumentError) end it "should require a listening port to be specified" do Proc.new { @server.listen(@listen_params.delete_if {|k,v| :port == k})}.should raise_error(ArgumentError) end it "should order a mongrel server to start" do @mock_mongrel.expects(:run) @server.listen(@listen_params) end it "should tell mongrel to listen on the specified address and port" do Mongrel::HttpServer.expects(:new).with("127.0.0.1", 31337).returns(@mock_mongrel) @server.listen(@listen_params) end it "should be listening" do Mongrel::HttpServer.expects(:new).returns(@mock_mongrel) @server.listen(@listen_params) @server.should be_listening end describe "when providing REST services" do it "should instantiate a handler at / for handling REST calls" do Puppet::Network::HTTP::MongrelREST.expects(:new).returns "myhandler" @mock_mongrel.expects(:register).with("/", "myhandler") @server.listen(@listen_params) end end end -describe "Puppet::Network::HTTP::Mongrel", "when turning off listening", :if => Puppet.features.mongrel?, :'fails_on_ruby_1.9.2' => true do +describe "Puppet::Network::HTTP::Mongrel", "when turning off listening", :if => Puppet.features.mongrel? do before do @mock_mongrel = mock('mongrel httpserver') @mock_mongrel.stubs(:run) @mock_mongrel.stubs(:register) Mongrel::HttpServer.stubs(:new).returns(@mock_mongrel) @server = Puppet::Network::HTTP::Mongrel.new @listen_params = { :address => "127.0.0.1", :port => 31337, :handlers => [ :node, :catalog ]} end it "should fail unless listening" do Proc.new { @server.unlisten }.should raise_error(RuntimeError) end it "should order mongrel server to stop" do @server.listen(@listen_params) @mock_mongrel.expects(:stop) @server.unlisten end it "should not be listening" do @server.listen(@listen_params) @mock_mongrel.stubs(:stop) @server.unlisten @server.should_not be_listening end end diff --git a/spec/unit/network/http/webrick/rest_spec.rb b/spec/unit/network/http/webrick/rest_spec.rb index 84a2b7791..1c3122d3f 100755 --- a/spec/unit/network/http/webrick/rest_spec.rb +++ b/spec/unit/network/http/webrick/rest_spec.rb @@ -1,180 +1,190 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/network/http' require 'webrick' require 'puppet/network/http/webrick/rest' describe Puppet::Network::HTTP::WEBrickREST do it "should include the Puppet::Network::HTTP::Handler module" do Puppet::Network::HTTP::WEBrickREST.ancestors.should be_include(Puppet::Network::HTTP::Handler) end - describe "when initializing", :'fails_on_ruby_1.9.2' => true do + describe "when initializing" do it "should call the Handler's initialization hook with its provided arguments as the server and handler" do - Puppet::Network::HTTP::WEBrickREST.any_instance.expects(:initialize_for_puppet).with(:server => "my", :handler => "arguments") - Puppet::Network::HTTP::WEBrickREST.new("my", "arguments") + server = WEBrick::HTTPServer.new(:BindAddress => '127.0.0.1', + # Probablistically going to succeed + # even if we run more than one test + # instance at once. + :Port => 40000 + rand(10000), + # Just discard any log output, thanks. + :Logger => stub_everything('logger')) + + Puppet::Network::HTTP::WEBrickREST.any_instance. + expects(:initialize_for_puppet).with(:server => server, :handler => "arguments") + + Puppet::Network::HTTP::WEBrickREST.new(server, "arguments") end end describe "when receiving a request" do before do @request = stub('webrick http request', :query => {}, :peeraddr => %w{eh boo host ip}, :client_cert => nil) @response = stub('webrick http response', :status= => true, :body= => true) @model_class = stub('indirected model class') @webrick = stub('webrick http server', :mount => true, :[] => {}) Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@model_class) @handler = Puppet::Network::HTTP::WEBrickREST.new(@webrick, :foo) end it "should delegate its :service method to its :process method" do @handler.expects(:process).with(@request, @response).returns "stuff" @handler.service(@request, @response).should == "stuff" end describe "when using the Handler interface" do it "should use the 'accept' request parameter as the Accept header" do @request.expects(:[]).with("accept").returns "foobar" @handler.accept_header(@request).should == "foobar" end it "should use the 'content-type' request header as the Content-Type header" do @request.expects(:[]).with("content-type").returns "foobar" @handler.content_type_header(@request).should == "foobar" end it "should use the request method as the http method" do @request.expects(:request_method).returns "FOO" @handler.http_method(@request).should == "FOO" end it "should return the request path as the path" do @request.expects(:path).returns "/foo/bar" @handler.path(@request).should == "/foo/bar" end it "should return the request body as the body" do @request.expects(:body).returns "my body" @handler.body(@request).should == "my body" end it "should set the response's 'content-type' header when setting the content type" do @response.expects(:[]=).with("content-type", "text/html") @handler.set_content_type(@response, "text/html") end it "should set the status and body on the response when setting the response for a successful query" do @response.expects(:status=).with 200 @response.expects(:body=).with "mybody" @handler.set_response(@response, "mybody", 200) end describe "when the result is a File" do before(:each) do stat = stub 'stat', :size => 100 @file = stub 'file', :stat => stat, :path => "/tmp/path" @file.stubs(:is_a?).with(File).returns(true) end it "should serve it" do @response.stubs(:[]=) @response.expects(:status=).with 200 @response.expects(:body=).with @file @handler.set_response(@response, @file, 200) end it "should set the Content-Length header" do @response.expects(:[]=).with('content-length', 100) @handler.set_response(@response, @file, 200) end end it "should set the status and message on the response when setting the response for a failed query" do @response.expects(:status=).with 400 @response.expects(:reason_phrase=).with "mybody" @handler.set_response(@response, "mybody", 400) end end describe "and determining the request parameters" do it "should include the HTTP request parameters, with the keys as symbols" do @request.stubs(:query).returns("foo" => "baz", "bar" => "xyzzy") result = @handler.params(@request) result[:foo].should == "baz" result[:bar].should == "xyzzy" end it "should CGI-decode the HTTP parameters" do encoding = CGI.escape("foo bar") @request.expects(:query).returns('foo' => encoding) result = @handler.params(@request) result[:foo].should == "foo bar" end it "should convert the string 'true' to the boolean" do @request.expects(:query).returns('foo' => "true") result = @handler.params(@request) result[:foo].should be_true end it "should convert the string 'false' to the boolean" do @request.expects(:query).returns('foo' => "false") result = @handler.params(@request) result[:foo].should be_false end it "should YAML-load and CGI-decode values that are YAML-encoded" do escaping = CGI.escape(YAML.dump(%w{one two})) @request.expects(:query).returns('foo' => escaping) result = @handler.params(@request) result[:foo].should == %w{one two} end it "should not allow clients to set the node via the request parameters" do @request.stubs(:query).returns("node" => "foo") @handler.stubs(:resolve_node) @handler.params(@request)[:node].should be_nil end it "should not allow clients to set the IP via the request parameters" do @request.stubs(:query).returns("ip" => "foo") @handler.params(@request)[:ip].should_not == "foo" end it "should pass the client's ip address to model find" do @request.stubs(:peeraddr).returns(%w{noidea dunno hostname ipaddress}) @handler.params(@request)[:ip].should == "ipaddress" end it "should set 'authenticated' to true if a certificate is present" do cert = stub 'cert', :subject => [%w{CN host.domain.com}] @request.stubs(:client_cert).returns cert @handler.params(@request)[:authenticated].should be_true end it "should set 'authenticated' to false if no certificate is present" do @request.stubs(:client_cert).returns nil @handler.params(@request)[:authenticated].should be_false end it "should pass the client's certificate name to model method if a certificate is present" do cert = stub 'cert', :subject => [%w{CN host.domain.com}] @request.stubs(:client_cert).returns cert @handler.params(@request)[:node].should == "host.domain.com" end it "should resolve the node name with an ip address look-up if no certificate is present" do @request.stubs(:client_cert).returns nil @handler.expects(:resolve_node).returns(:resolved_node) @handler.params(@request)[:node].should == :resolved_node end end end end diff --git a/spec/unit/parser/ast/function_spec.rb b/spec/unit/parser/ast/function_spec.rb index d683b122b..4ad176dab 100755 --- a/spec/unit/parser/ast/function_spec.rb +++ b/spec/unit/parser/ast/function_spec.rb @@ -1,92 +1,92 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Parser::AST::Function do before :each do @scope = mock 'scope' end describe "when initializing" do it "should not fail if the function doesn't exist" do Puppet::Parser::Functions.stubs(:function).returns(false) lambda{ Puppet::Parser::AST::Function.new :name => "dontexist" }.should_not raise_error(Puppet::ParseError) end end it "should return its representation with to_s" do args = stub 'args', :is_a? => true, :to_s => "[a, b]" Puppet::Parser::AST::Function.new(:name => "func", :arguments => args).to_s.should == "func(a, b)" end describe "when evaluating" do it "should fail if the function doesn't exist" do Puppet::Parser::Functions.stubs(:function).returns(false) func = Puppet::Parser::AST::Function.new :name => "dontexist" lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError) end it "should fail if the function is a statement used as rvalue" do Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(false) func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :rvalue lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError, "Function 'exist' does not return a value") end it "should fail if the function is an rvalue used as statement" do Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(true) func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError,"Function 'exist' must be the value of a statement") end - it "should evaluate its arguments", :'fails_on_ruby_1.9.2' => true do + it "should evaluate its arguments" do argument = stub 'arg' Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument @scope.stubs(:function_exist) - argument.expects(:safeevaluate).with(@scope).returns("argument") + argument.expects(:safeevaluate).with(@scope).returns(["argument"]) func.evaluate(@scope) end it "should call the underlying ruby function" do argument = stub 'arg', :safeevaluate => ["nothing"] Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument @scope.expects(:function_exist).with(["nothing"]) func.evaluate(@scope) end it "should convert :undef to '' in arguments" do argument = stub 'arg', :safeevaluate => ["foo", :undef, "bar"] Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument @scope.expects(:function_exist).with(["foo", "", "bar"]) func.evaluate(@scope) end it "should return the ruby function return for rvalue functions" do argument = stub 'arg', :safeevaluate => ["nothing"] Puppet::Parser::Functions.stubs(:function).with("exist").returns(true) func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument @scope.stubs(:function_exist).with(["nothing"]).returns("returning") func.evaluate(@scope).should == "returning" end end end diff --git a/spec/unit/parser/ast/selector_spec.rb b/spec/unit/parser/ast/selector_spec.rb index 76afec271..771b5df6c 100755 --- a/spec/unit/parser/ast/selector_spec.rb +++ b/spec/unit/parser/ast/selector_spec.rb @@ -1,138 +1,86 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Parser::AST::Selector do - before :each do - @scope = Puppet::Parser::Scope.new + let :scope do Puppet::Parser::Scope.new end + + # Take a code expression containing a selector, and return that portion of + # the AST. This does the magic required to make that legal and all. + def parse(selector) + Puppet::Parser::Parser.new(scope.environment). + parse("$foo = #{selector}"). + code[0].value # extract only the selector end - describe "when evaluating", :'fails_on_ruby_1.9.2' => true do - - before :each do - @param = stub 'param' - @param.stubs(:safeevaluate).with(@scope).returns("value") - - @value1 = stub 'value1' - @param1 = stub_everything 'param1' - @param1.stubs(:safeevaluate).with(@scope).returns(@param1) - @param1.stubs(:respond_to?).with(:downcase).returns(false) - @value1.stubs(:param).returns(@param1) - @value1.stubs(:value).returns(@value1) - - @value2 = stub 'value2' - @param2 = stub_everything 'param2' - @param2.stubs(:safeevaluate).with(@scope).returns(@param2) - @param2.stubs(:respond_to?).with(:downcase).returns(false) - @value2.stubs(:param).returns(@param2) - @value2.stubs(:value).returns(@value2) - - @values = stub 'values', :instance_of? => true - @values.stubs(:each).multiple_yields(@value1, @value2) - - @selector = Puppet::Parser::AST::Selector.new :param => @param, :values => @values - @selector.stubs(:fail) - end - + describe "when evaluating" do it "should evaluate param" do - @param.expects(:safeevaluate).with(@scope) - - @selector.evaluate(@scope) - end - - it "should scan each option" do - @values.expects(:each).multiple_yields(@value1, @value2) - - @selector.evaluate(@scope) + selector = parse 'value ? { default => result }' + selector.param.expects(:safeevaluate) + selector.evaluate(scope) end - describe "when scanning values" do - it "should evaluate first matching option" do - @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) - @value2.expects(:safeevaluate).with(@scope) + it "should try to match each option in sequence" do + selector = parse '"a" ? { "a" => "a", "b" => "b", default => "default" }' - @selector.evaluate(@scope) + order = sequence('evaluation of matching options') + selector.values.each do |slot| + slot.param.expects(:evaluate_match).in_sequence(order).returns(false) end - it "should return the first matching evaluated option" do - @param2.stubs(:evaluate_match).with { |*arg| arg[0] == "value" }.returns(true) - @value2.stubs(:safeevaluate).with(@scope).returns(:result) + selector.evaluate(scope) + end - @selector.evaluate(@scope).should == :result + describe "when scanning values" do + it "should evaluate and return first matching option" do + selector = parse '"b" ? { "a" => "=a", "b" => "=b", "c" => "=c" }' + selector.evaluate(scope).should == '=b' end it "should evaluate the default option if none matched" do - @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true) - @value1.expects(:safeevaluate).with(@scope).returns(@param1) - - @selector.evaluate(@scope) + selector = parse '"a" ? { "b" => "=b", default => "=default" }' + selector.evaluate(scope).should == "=default" end - it "should return the default evaluated option if none matched" do - result = stub 'result' - @param1.stubs(:is_a?).with(Puppet::Parser::AST::Default).returns(true) - @value1.stubs(:safeevaluate).returns(result) - - @selector.evaluate(@scope).should == result + it "should return the default even if that isn't the last option" do + selector = parse '"a" ? { "b" => "=b", default => "=default", "c" => "=c" }' + selector.evaluate(scope).should == "=default" end - it "should return nil if nothing matched" do - @selector.evaluate(@scope).should be_nil - end - - it "should delegate matching to evaluate_match" do - @param1.expects(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope } - - @selector.evaluate(@scope) - end - - it "should evaluate the matching param" do - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - - @value1.expects(:safeevaluate).with(@scope) - - @selector.evaluate(@scope) - end - - it "should return this evaluated option if it matches" do - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.stubs(:safeevaluate).with(@scope).returns(:result) - - @selector.evaluate(@scope).should == :result + it "should raise ParseError if nothing matched, and no default" do + selector = parse '"a" ? { "b" => "=b" }' + msg = /No matching value for selector param/ + expect { selector.evaluate(scope) }.to raise_error Puppet::ParseError, msg end it "should unset scope ephemeral variables after option evaluation" do - @scope.stubs(:ephemeral_level).returns(:level) - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.stubs(:safeevaluate).with(@scope).returns(:result) - - @scope.expects(:unset_ephemeral_var).with(:level) - - @selector.evaluate(@scope) + selector = parse '"a" ? { "a" => "=a" }' + scope.expects(:unset_ephemeral_var).with(scope.ephemeral_level) + selector.evaluate(scope) end it "should not leak ephemeral variables even if evaluation fails" do - @scope.stubs(:ephemeral_level).returns(:level) - @param1.stubs(:evaluate_match).with { |*arg| arg[0] == "value" and arg[1] == @scope }.returns(true) - @value1.stubs(:safeevaluate).with(@scope).raises - - @scope.expects(:unset_ephemeral_var).with(:level) - - lambda { @selector.evaluate(@scope) }.should raise_error - end - - it "should fail if there is no default" do - @selector.expects(:fail) - - @selector.evaluate(@scope) + selector = parse '"a" ? { "b" => "=b" }' + scope.expects(:unset_ephemeral_var).with(scope.ephemeral_level) + expect { selector.evaluate(scope) }.to raise_error end end end + describe "when converting to string" do - it "should produce a string version of this selector" do - values = Puppet::Parser::AST::ASTArray.new :children => [ Puppet::Parser::AST::ResourceParam.new(:param => "type", :value => "value", :add => false) ] - param = Puppet::Parser::AST::Variable.new :value => "myvar" - selector = Puppet::Parser::AST::Selector.new :param => param, :values => values - selector.to_s.should == "$myvar ? { type => value }" + it "should work with a single match" do + parse('$input ? { "a" => "a+" }').to_s.should == '$input ? { "a" => "a+" }' + end + + it "should work with multiple matches" do + parse('$input ? { "a" => "a+", "b" => "b+" }').to_s. + should == '$input ? { "a" => "a+", "b" => "b+" }' + end + + it "should preserve order of inputs" do + match = ('a' .. 'z').map {|x| "#{x} => #{x}" }.join(', ') + selector = parse "$input ? { #{match} }" + + selector.to_s.should == "$input ? { #{match} }" end end end diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index 411d1b862..d0f7a5b5e 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -1,822 +1,822 @@ #!/usr/bin/env rspec require 'spec_helper' class CompilerTestResource attr_accessor :builtin, :virtual, :evaluated, :type, :title def initialize(type, title) @type = type @title = title end def [](attr) return nil if attr == :stage :main end def ref "#{type.to_s.capitalize}[#{title}]" end def evaluated? @evaluated end def builtin_type? @builtin end def virtual? @virtual end def evaluate end def file "/fake/file/goes/here" end def line "42" end end describe Puppet::Parser::Compiler do include PuppetSpec::Files def resource(type, title) Puppet::Parser::Resource.new(type, title, :scope => @scope) end before :each do # Push me faster, I wanna go back in time! (Specifically, freeze time # across the test since we have a bunch of version == timestamp code # hidden away in the implementation and we keep losing the race.) # --daniel 2011-04-21 now = Time.now Time.stubs(:now).returns(now) @node = Puppet::Node.new "testnode" @known_resource_types = Puppet::Resource::TypeCollection.new "development" @compiler = Puppet::Parser::Compiler.new(@node) @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => stub('source')) @scope_resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope) @scope.resource = @scope_resource @compiler.environment.stubs(:known_resource_types).returns @known_resource_types end it "should have a class method that compiles, converts, and returns a catalog" do compiler = stub 'compiler' Puppet::Parser::Compiler.expects(:new).with(@node).returns compiler catalog = stub 'catalog' compiler.expects(:compile).returns catalog converted_catalog = stub 'converted_catalog' catalog.expects(:to_resource).returns converted_catalog Puppet::Parser::Compiler.compile(@node).should equal(converted_catalog) end it "should fail intelligently when a class-level compile fails" do Puppet::Parser::Compiler.expects(:new).raises ArgumentError lambda { Puppet::Parser::Compiler.compile(@node) }.should raise_error(Puppet::Error) end it "should use the node's environment as its environment" do @compiler.environment.should equal(@node.environment) end it "should include the resource type collection helper" do Puppet::Parser::Compiler.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper) end it "should be able to return a class list containing all added classes" do @compiler.add_class "" @compiler.add_class "one" @compiler.add_class "two" @compiler.classlist.sort.should == %w{one two}.sort end describe "when initializing" do it "should set its node attribute" do @compiler.node.should equal(@node) end it "should detect when ast nodes are absent" do @compiler.ast_nodes?.should be_false end it "should detect when ast nodes are present" do @known_resource_types.expects(:nodes?).returns true @compiler.ast_nodes?.should be_true end it "should copy the known_resource_types version to the catalog" do @compiler.catalog.version.should == @known_resource_types.version end it "should copy any node classes into the class list" do node = Puppet::Node.new("mynode") node.classes = %w{foo bar} compiler = Puppet::Parser::Compiler.new(node) compiler.classlist.should =~ ['foo', 'bar'] end it "should transform node class hashes into a class list" do node = Puppet::Node.new("mynode") node.classes = {'foo'=>{'one'=>'1'}, 'bar'=>{'two'=>'2'}} compiler = Puppet::Parser::Compiler.new(node) compiler.classlist.should =~ ['foo', 'bar'] end it "should add a 'main' stage to the catalog" do @compiler.catalog.resource(:stage, :main).should be_instance_of(Puppet::Parser::Resource) end end describe "when managing scopes" do it "should create a top scope" do @compiler.topscope.should be_instance_of(Puppet::Parser::Scope) end it "should be able to create new scopes" do @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope) end it "should set the parent scope of the new scope to be the passed-in parent" do scope = mock 'scope' newscope = @compiler.newscope(scope) newscope.parent.should equal(scope) end it "should set the parent scope of the new scope to its topscope if the parent passed in is nil" do scope = mock 'scope' newscope = @compiler.newscope(nil) newscope.parent.should equal(@compiler.topscope) end end describe "when compiling" do def compile_methods [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated, :finish, :store, :extract, :evaluate_relationships] end # Stub all of the main compile methods except the ones we're specifically interested in. def compile_stub(*except) (compile_methods - except).each { |m| @compiler.stubs(m) } end it "should set node parameters as variables in the top scope" do params = {"a" => "b", "c" => "d"} @node.stubs(:parameters).returns(params) compile_stub(:set_node_parameters) @compiler.compile @compiler.topscope['a'].should == "b" @compiler.topscope['c'].should == "d" end it "should set the client and server versions on the catalog" do params = {"clientversion" => "2", "serverversion" => "3"} @node.stubs(:parameters).returns(params) compile_stub(:set_node_parameters) @compiler.compile @compiler.catalog.client_version.should == "2" @compiler.catalog.server_version.should == "3" end it "should evaluate any existing classes named in the node" do classes = %w{one two three four} main = stub 'main' one = stub 'one', :name => "one" three = stub 'three', :name => "three" @node.stubs(:name).returns("whatever") @node.stubs(:classes).returns(classes) @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope) @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes } end it "should evaluate any parameterized classes named in the node" do classes = {'foo'=>{'1'=>'one'}, 'bar'=>{'2'=>'two'}} @node.stubs(:classes).returns(classes) @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope) @compiler.compile end it "should evaluate the main class if it exists" do compile_stub(:evaluate_main) main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "") main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) } @compiler.topscope.expects(:source=).with(main_class) @compiler.compile end it "should create a new, empty 'main' if no main class exists" do compile_stub(:evaluate_main) @compiler.compile @known_resource_types.find_hostclass([""], "").should be_instance_of(Puppet::Resource::Type) end it "should add an edge between the main stage and main class" do @compiler.compile (stage = @compiler.catalog.resource(:stage, "main")).should be_instance_of(Puppet::Parser::Resource) (klass = @compiler.catalog.resource(:class, "")).should be_instance_of(Puppet::Parser::Resource) @compiler.catalog.edge?(stage, klass).should be_true end it "should evaluate any node classes" do @node.stubs(:classes).returns(%w{one two three four}) @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope) @compiler.send(:evaluate_node_classes) end it "should evaluate all added collections" do colls = [] # And when the collections fail to evaluate. colls << mock("coll1-false") colls << mock("coll2-false") colls.each { |c| c.expects(:evaluate).returns(false) } @compiler.add_collection(colls[0]) @compiler.add_collection(colls[1]) compile_stub(:evaluate_generators) @compiler.compile end it "should ignore builtin resources" do resource = resource(:file, "testing") @compiler.add_resource(@scope, resource) resource.expects(:evaluate).never @compiler.compile end it "should evaluate unevaluated resources" do resource = CompilerTestResource.new(:file, "testing") @compiler.add_resource(@scope, resource) # We have to now mark the resource as evaluated resource.expects(:evaluate).with { |*whatever| resource.evaluated = true } @compiler.compile end it "should not evaluate already-evaluated resources" do resource = resource(:file, "testing") resource.stubs(:evaluated?).returns true @compiler.add_resource(@scope, resource) resource.expects(:evaluate).never @compiler.compile end it "should evaluate unevaluated resources created by evaluating other resources" do resource = CompilerTestResource.new(:file, "testing") @compiler.add_resource(@scope, resource) resource2 = CompilerTestResource.new(:file, "other") # We have to now mark the resource as evaluated resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) } resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true } @compiler.compile end describe "when finishing" do before do @compiler.send(:evaluate_main) @catalog = @compiler.catalog end def add_resource(name, parent = nil) resource = Puppet::Parser::Resource.new "file", name, :scope => @scope @compiler.add_resource(@scope, resource) @catalog.add_edge(parent, resource) if parent resource end it "should call finish() on all resources" do # Add a resource that does respond to :finish resource = Puppet::Parser::Resource.new "file", "finish", :scope => @scope resource.expects(:finish) @compiler.add_resource(@scope, resource) # And one that does not dnf_resource = stub_everything "dnf", :ref => "File[dnf]", :type => "file" @compiler.add_resource(@scope, dnf_resource) @compiler.send(:finish) end it "should call finish() in add_resource order" do resources = sequence('resources') resource1 = add_resource("finish1") resource1.expects(:finish).in_sequence(resources) resource2 = add_resource("finish2") resource2.expects(:finish).in_sequence(resources) @compiler.send(:finish) end it "should add each container's metaparams to its contained resources" do main = @catalog.resource(:class, :main) main[:noop] = true resource1 = add_resource("meh", main) @compiler.send(:finish) resource1[:noop].should be_true end it "should add metaparams recursively" do main = @catalog.resource(:class, :main) main[:noop] = true resource1 = add_resource("meh", main) resource2 = add_resource("foo", resource1) @compiler.send(:finish) resource2[:noop].should be_true end it "should prefer metaparams from immediate parents" do main = @catalog.resource(:class, :main) main[:noop] = true resource1 = add_resource("meh", main) resource2 = add_resource("foo", resource1) resource1[:noop] = false @compiler.send(:finish) resource2[:noop].should be_false end it "should merge tags downward" do main = @catalog.resource(:class, :main) main.tag("one") resource1 = add_resource("meh", main) resource1.tag "two" resource2 = add_resource("foo", resource1) @compiler.send(:finish) resource2.tags.should be_include("one") resource2.tags.should be_include("two") end it "should work if only middle resources have metaparams set" do main = @catalog.resource(:class, :main) resource1 = add_resource("meh", main) resource1[:noop] = true resource2 = add_resource("foo", resource1) @compiler.send(:finish) resource2[:noop].should be_true end end it "should return added resources in add order" do resource1 = resource(:file, "yay") @compiler.add_resource(@scope, resource1) resource2 = resource(:file, "youpi") @compiler.add_resource(@scope, resource2) @compiler.resources.should == [resource1, resource2] end it "should add resources that do not conflict with existing resources" do resource = resource(:file, "yay") @compiler.add_resource(@scope, resource) @compiler.catalog.should be_vertex(resource) end it "should fail to add resources that conflict with existing resources" do path = make_absolute("/foo") file1 = Puppet::Type.type(:file).new :path => path file2 = Puppet::Type.type(:file).new :path => path @compiler.add_resource(@scope, file1) lambda { @compiler.add_resource(@scope, file2) }.should raise_error(Puppet::Resource::Catalog::DuplicateResourceError) end it "should add an edge from the scope resource to the added resource" do resource = resource(:file, "yay") @compiler.add_resource(@scope, resource) @compiler.catalog.should be_edge(@scope.resource, resource) end it "should not add non-class resources that don't specify a stage to the 'main' stage" do main = @compiler.catalog.resource(:stage, :main) resource = resource(:file, "foo") @compiler.add_resource(@scope, resource) @compiler.catalog.should_not be_edge(main, resource) end it "should not add any parent-edges to stages" do stage = resource(:stage, "other") @compiler.add_resource(@scope, stage) @scope.resource = resource(:class, "foo") @compiler.catalog.edge?(@scope.resource, stage).should be_false end it "should not attempt to add stages to other stages" do other_stage = resource(:stage, "other") second_stage = resource(:stage, "second") @compiler.add_resource(@scope, other_stage) @compiler.add_resource(@scope, second_stage) second_stage[:stage] = "other" @compiler.catalog.edge?(other_stage, second_stage).should be_false end it "should have a method for looking up resources" do resource = resource(:yay, "foo") @compiler.add_resource(@scope, resource) @compiler.findresource("Yay[foo]").should equal(resource) end it "should be able to look resources up by type and title" do resource = resource(:yay, "foo") @compiler.add_resource(@scope, resource) @compiler.findresource("Yay", "foo").should equal(resource) end it "should not evaluate virtual defined resources" do resource = resource(:file, "testing") resource.virtual = true @compiler.add_resource(@scope, resource) resource.expects(:evaluate).never @compiler.compile end end describe "when evaluating collections" do it "should evaluate each collection" do 2.times { |i| coll = mock 'coll%s' % i @compiler.add_collection(coll) # This is the hard part -- we have to emulate the fact that # collections delete themselves if they are done evaluating. coll.expects(:evaluate).with do @compiler.delete_collection(coll) end } @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections } end it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do coll = stub 'coll', :evaluate => false coll.expects(:resources).returns(nil) @compiler.add_collection(coll) lambda { @compiler.compile }.should_not raise_error end it "should fail when there are unevaluated resource collections that refer to a specific resource" do coll = stub 'coll', :evaluate => false coll.expects(:resources).returns(:something) @compiler.add_collection(coll) lambda { @compiler.compile }.should raise_error Puppet::ParseError, 'Failed to realize virtual resources something' end it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do coll = stub 'coll', :evaluate => false coll.expects(:resources).returns([:one, :two]) @compiler.add_collection(coll) lambda { @compiler.compile }.should raise_error Puppet::ParseError, 'Failed to realize virtual resources one, two' end end describe "when evaluating relationships" do it "should evaluate each relationship with its catalog" do dep = stub 'dep' dep.expects(:evaluate).with(@compiler.catalog) @compiler.add_relationship dep @compiler.evaluate_relationships end end describe "when told to evaluate missing classes" do it "should fail if there's no source listed for the scope" do scope = stub 'scope', :source => nil proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError) end it "should raise an error if a class is not found" do @scope.expects(:find_hostclass).with("notfound").returns(nil) lambda{ @compiler.evaluate_classes(%w{notfound}, @scope) }.should raise_error(Puppet::Error, /Could not find class/) end it "should raise an error when it can't find class" do klasses = {'foo'=>nil} @node.classes = klasses @compiler.topscope.stubs(:find_hostclass).with('foo').returns(nil) lambda{ @compiler.compile }.should raise_error(Puppet::Error, /Could not find class foo for testnode/) end end describe "when evaluating found classes" do before do @class = stub 'class', :name => "my::class" @scope.stubs(:find_hostclass).with("myclass").returns(@class) @resource = stub 'resource', :ref => "Class[myclass]", :type => "file" end it "should evaluate each class" do @compiler.catalog.stubs(:tag) @class.expects(:ensure_in_catalog).with(@scope) @scope.stubs(:class_scope).with(@class) @compiler.evaluate_classes(%w{myclass}, @scope) end describe "and the classes are specified as a hash with parameters" do before do @node.classes = {} @ast_obj = Puppet::Parser::AST::String.new(:value => 'foo') end # Define the given class with default parameters def define_class(name, parameters) @node.classes[name] = parameters klass = Puppet::Resource::Type.new(:hostclass, name, :arguments => {'1' => @ast_obj, '2' => @ast_obj}) @compiler.topscope.known_resource_types.add klass end def compile @catalog = @compiler.compile end it "should record which classes are evaluated" do classes = {'foo'=>{}, 'bar::foo'=>{}, 'bar'=>{}} classes.each { |c, params| define_class(c, params) } compile() classes.each { |name, p| @catalog.classes.should include(name) } end it "should provide default values for parameters that have no values specified" do define_class('foo', {}) compile() @catalog.resource(:class, 'foo')['1'].should == "foo" end it "should use any provided values" do define_class('foo', {'1' => 'real_value'}) compile() @catalog.resource(:class, 'foo')['1'].should == "real_value" end it "should support providing some but not all values" do define_class('foo', {'1' => 'real_value'}) compile() @catalog.resource(:class, 'Foo')['1'].should == "real_value" @catalog.resource(:class, 'Foo')['2'].should == "foo" end - it "should ensure each node class is in catalog and has appropriate tags", :'fails_on_ruby_1.9.2' => true do + it "should ensure each node class is in catalog and has appropriate tags" do klasses = ['bar::foo'] @node.classes = klasses ast_obj = Puppet::Parser::AST::String.new(:value => 'foo') klasses.each do |name| klass = Puppet::Resource::Type.new(:hostclass, name, :arguments => {'1' => ast_obj, '2' => ast_obj}) @compiler.topscope.known_resource_types.add klass end catalog = @compiler.compile r2 = catalog.resources.detect {|r| r.title == 'Bar::Foo' } r2.tags.should =~ ['bar::foo', 'class', 'bar', 'foo'] end end it "should fail if required parameters are missing" do klass = {'foo'=>{'1'=>'one'}} @node.classes = klass klass = Puppet::Resource::Type.new(:hostclass, 'foo', :arguments => {'1' => nil, '2' => nil}) @compiler.topscope.known_resource_types.add klass lambda { @compiler.compile }.should raise_error(Puppet::ParseError, "Must pass 2 to Class[Foo]") end it "should fail if invalid parameters are passed" do klass = {'foo'=>{'3'=>'one'}} @node.classes = klass klass = Puppet::Resource::Type.new(:hostclass, 'foo', :arguments => {}) @compiler.topscope.known_resource_types.add klass lambda { @compiler.compile }.should raise_error(Puppet::ParseError, "Invalid parameter 3") end it "should ensure class is in catalog without params" do @node.classes = klasses = {'foo'=>nil} foo = Puppet::Resource::Type.new(:hostclass, 'foo') @compiler.topscope.known_resource_types.add foo catalog = @compiler.compile catalog.classes.should include 'foo' end it "should not evaluate the resources created for found classes unless asked" do @compiler.catalog.stubs(:tag) @resource.expects(:evaluate).never @class.expects(:ensure_in_catalog).returns(@resource) @scope.stubs(:class_scope).with(@class) @compiler.evaluate_classes(%w{myclass}, @scope) end it "should immediately evaluate the resources created for found classes when asked" do @compiler.catalog.stubs(:tag) @resource.expects(:evaluate) @class.expects(:ensure_in_catalog).returns(@resource) @scope.stubs(:class_scope).with(@class) @compiler.evaluate_classes(%w{myclass}, @scope, false) end it "should skip classes that have already been evaluated" do @compiler.catalog.stubs(:tag) @scope.stubs(:class_scope).with(@class).returns("something") @compiler.expects(:add_resource).never @resource.expects(:evaluate).never Puppet::Parser::Resource.expects(:new).never @compiler.evaluate_classes(%w{myclass}, @scope, false) end it "should skip classes previously evaluated with different capitalization" do @compiler.catalog.stubs(:tag) @scope.stubs(:find_hostclass).with("MyClass").returns(@class) @scope.stubs(:class_scope).with(@class).returns("something") @compiler.expects(:add_resource).never @resource.expects(:evaluate).never Puppet::Parser::Resource.expects(:new).never @compiler.evaluate_classes(%w{MyClass}, @scope, false) end end describe "when evaluating AST nodes with no AST nodes present" do it "should do nothing" do @compiler.expects(:ast_nodes?).returns(false) @compiler.known_resource_types.expects(:nodes).never Puppet::Parser::Resource.expects(:new).never @compiler.send(:evaluate_ast_node) end end describe "when evaluating AST nodes with AST nodes present" do before do @compiler.known_resource_types.stubs(:nodes?).returns true # Set some names for our test @node.stubs(:names).returns(%w{a b c}) @compiler.known_resource_types.stubs(:node).with("a").returns(nil) @compiler.known_resource_types.stubs(:node).with("b").returns(nil) @compiler.known_resource_types.stubs(:node).with("c").returns(nil) # It should check this last, of course. @compiler.known_resource_types.stubs(:node).with("default").returns(nil) end it "should fail if the named node cannot be found" do proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError) end it "should evaluate the first node class matching the node name" do node_class = stub 'node', :name => "c", :evaluate_code => nil @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node" node_class.expects(:ensure_in_catalog).returns(node_resource) @compiler.compile end it "should match the default node if no matching node can be found" do node_class = stub 'node', :name => "default", :evaluate_code => nil @compiler.known_resource_types.stubs(:node).with("default").returns(node_class) node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil, :type => "node" node_class.expects(:ensure_in_catalog).returns(node_resource) @compiler.compile end it "should evaluate the node resource immediately rather than using lazy evaluation" do node_class = stub 'node', :name => "c" @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) node_resource = stub 'node resource', :ref => "Node[c]", :type => "node" node_class.expects(:ensure_in_catalog).returns(node_resource) node_resource.expects(:evaluate) @compiler.send(:evaluate_ast_node) end it "should set the node's scope as the top scope" do node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil, :type => "node" node_class = stub 'node', :name => "c", :ensure_in_catalog => node_resource @compiler.known_resource_types.stubs(:node).with("c").returns(node_class) # The #evaluate method normally does this. scope = stub 'scope', :source => "mysource" @compiler.topscope.expects(:class_scope).with(node_class).returns(scope) node_resource.stubs(:evaluate) @compiler.stubs :create_settings_scope @compiler.compile @compiler.topscope.should equal(scope) end end describe "when managing resource overrides" do before do @override = stub 'override', :ref => "File[/foo]", :type => "my" @resource = resource(:file, "/foo") end it "should be able to store overrides" do lambda { @compiler.add_override(@override) }.should_not raise_error end it "should apply overrides to the appropriate resources" do @compiler.add_resource(@scope, @resource) @resource.expects(:merge).with(@override) @compiler.add_override(@override) @compiler.compile end it "should accept overrides before the related resource has been created" do @resource.expects(:merge).with(@override) # First store the override @compiler.add_override(@override) # Then the resource @compiler.add_resource(@scope, @resource) # And compile, so they get resolved @compiler.compile end it "should fail if the compile is finished and resource overrides have not been applied" do @compiler.add_override(@override) lambda { @compiler.compile }.should raise_error Puppet::ParseError, 'Could not find resource(s) File[/foo] for overriding' end end end diff --git a/spec/unit/parser/functions/fail_spec.rb b/spec/unit/parser/functions/fail_spec.rb new file mode 100755 index 000000000..bd685ae7a --- /dev/null +++ b/spec/unit/parser/functions/fail_spec.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +describe "the 'fail' parser function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end + + let :scope do + scope = Puppet::Parser::Scope.new + scope.stubs(:environment).returns(nil) + scope + end + + it "should exist" do + Puppet::Parser::Functions.function(:fail).should == "function_fail" + end + + it "should raise a parse error if invoked" do + expect { scope.function_fail([]) }.to raise_error Puppet::ParseError + end + + it "should join arguments into a string in the error" do + expect { scope.function_fail(["hello", "world"]) }.to raise_error /hello world/ + end +end diff --git a/spec/unit/parser/functions/file_spec.rb b/spec/unit/parser/functions/file_spec.rb new file mode 100755 index 000000000..901b75019 --- /dev/null +++ b/spec/unit/parser/functions/file_spec.rb @@ -0,0 +1,51 @@ +#!/usr/bin/env rspec +require 'spec_helper' +require 'puppet_spec/files' + +describe "the 'file' function" do + include PuppetSpec::Files + + before :all do + Puppet::Parser::Functions.autoloader.loadall + end + + let :scope do Puppet::Parser::Scope.new end + + it "should exist" do + Puppet::Parser::Functions.function("file").should == "function_file" + end + + def with_file_content(content) + path = tmpfile('file-function') + file = File.new(path, 'w') + file.sync = true + file.print content + yield path + end + + it "should read a file" do + with_file_content('file content') do |name| + scope.function_file([name]).should == "file content" + end + end + + it "should return the first file if given two files" do + with_file_content('one') do |one| + with_file_content('two') do |two| + scope.function_file([one, two]).should == "one" + end + end + end + + it "should not fail when some files are absent" do + expect { + with_file_content('one') do |one| + scope.function_file(["/this-should-not-exist", one]).should == 'one' + end + }.should_not raise_error + end + + it "should fail when all files are absent" do + expect { scope.function_file(['one']) }.to raise_error Puppet::ParseError + end +end diff --git a/spec/unit/parser/functions/generate_spec.rb b/spec/unit/parser/functions/generate_spec.rb index e50805393..42cf988ff 100755 --- a/spec/unit/parser/functions/generate_spec.rb +++ b/spec/unit/parser/functions/generate_spec.rb @@ -1,85 +1,122 @@ #!/usr/bin/env rspec require 'spec_helper' describe "the generate function" do + include PuppetSpec::Files + before :all do Puppet::Parser::Functions.autoloader.loadall end let(:scope) { Puppet::Parser::Scope.new } it "should exist" do Puppet::Parser::Functions.function("generate").should == "function_generate" end - it " accept a fully-qualified path as a command" do + it "accept a fully-qualified path as a command" do command = File.expand_path('/command/foo') Dir.expects(:chdir).with(File.dirname(command)).returns("yay") scope.function_generate([command]).should == "yay" end it "should not accept a relative path as a command" do lambda { scope.function_generate(["command"]) }.should raise_error(Puppet::ParseError) end it "should not accept a command containing illegal characters" do lambda { scope.function_generate([File.expand_path('/##/command')]) }.should raise_error(Puppet::ParseError) end it "should not accept a command containing spaces" do lambda { scope.function_generate([File.expand_path('/com mand')]) }.should raise_error(Puppet::ParseError) end it "should not accept a command containing '..'" do command = File.expand_path("/command/../") lambda { scope.function_generate([command]) }.should raise_error(Puppet::ParseError) end it "should execute the generate script with the correct working directory" do command = File.expand_path("/command") Dir.expects(:chdir).with(File.dirname(command)).returns("yay") scope.function_generate([command]).should == 'yay' end describe "on Windows" do before :each do Puppet.features.stubs(:microsoft_windows?).returns(true) end it "should accept lower-case drive letters" do command = 'd:/command/foo' Dir.expects(:chdir).with(File.dirname(command)).returns("yay") scope.function_generate([command]).should == 'yay' end it "should accept upper-case drive letters" do command = 'D:/command/foo' Dir.expects(:chdir).with(File.dirname(command)).returns("yay") scope.function_generate([command]).should == 'yay' end it "should accept forward and backslashes in the path" do command = 'D:\command/foo\bar' Dir.expects(:chdir).with(File.dirname(command)).returns("yay") scope.function_generate([command]).should == 'yay' end it "should reject colons when not part of the drive letter" do lambda { scope.function_generate(['C:/com:mand']) }.should raise_error(Puppet::ParseError) end it "should reject root drives" do lambda { scope.function_generate(['C:/']) }.should raise_error(Puppet::ParseError) end end describe "on non-Windows" do before :each do Puppet.features.stubs(:microsoft_windows?).returns(false) end it "should reject backslashes" do lambda { scope.function_generate(['/com\\mand']) }.should raise_error(Puppet::ParseError) end end + + let :command do + cmd = tmpfile('function_generate') + + if Puppet.features.microsoft_windows? + cmd += '.bat' + text = '@echo off' + "\n" + 'echo a-%1 b-%2' + else + text = '#!/bin/sh' + "\n" + 'echo a-$1 b-$2' + end + + File.open(cmd, 'w') {|fh| fh.puts text } + File.chmod 0700, cmd + cmd + end + + it "should call generator with no arguments" do + scope.function_generate([command]).should == "a- b-\n" + end + + it "should call generator with one argument" do + scope.function_generate([command, 'one']).should == "a-one b-\n" + end + + it "should call generator with wo arguments" do + scope.function_generate([command, 'one', 'two']).should == "a-one b-two\n" + end + + it "should fail if generator is not absolute" do + expect { scope.function_generate(['boo']) }.to raise_error Puppet::ParseError + end + + it "should fail if generator fails" do + expect { scope.function_generate(['/boo']) }.to raise_error Puppet::ParseError + end end diff --git a/spec/unit/parser/functions/include_spec.rb b/spec/unit/parser/functions/include_spec.rb index 15206cd7c..5f86049a8 100755 --- a/spec/unit/parser/functions/include_spec.rb +++ b/spec/unit/parser/functions/include_spec.rb @@ -1,35 +1,40 @@ #!/usr/bin/env rspec require 'spec_helper' describe "the 'include' function" do before :all do Puppet::Parser::Functions.autoloader.loadall end before :each do Puppet::Node::Environment.stubs(:current).returns(nil) @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) @scope = Puppet::Parser::Scope.new(:compiler => @compiler) end it "should exist" do Puppet::Parser::Functions.function("include").should == "function_include" end it "should include a single class" do inc = "foo" @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == [inc]}.returns([inc]) @scope.function_include("foo") end it "should include multiple classes" do inc = ["foo","bar"] @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| klasses == inc}.returns(inc) @scope.function_include(["foo","bar"]) end it "should not lazily evaluate the included class" do @compiler.expects(:evaluate_classes).with {|klasses,parser,lazy| lazy == false}.returns("foo") @scope.function_include("foo") end + + it "should raise if the class is not found" do + @scope.stubs(:source).returns(true) + expect { @scope.function_include("nosuchclass") }.to raise_error Puppet::Error + end end diff --git a/spec/unit/parser/functions/inline_template_spec.rb b/spec/unit/parser/functions/inline_template_spec.rb index 47dcae15e..1b1d1bdcd 100755 --- a/spec/unit/parser/functions/inline_template_spec.rb +++ b/spec/unit/parser/functions/inline_template_spec.rb @@ -1,61 +1,61 @@ #!/usr/bin/env rspec require 'spec_helper' -describe "the inline_template function", :'fails_on_ruby_1.9.2' => true do +describe "the inline_template function" do before :all do Puppet::Parser::Functions.autoloader.loadall end before :each do @scope = Puppet::Parser::Scope.new end it "should exist" do Puppet::Parser::Functions.function("inline_template").should == "function_inline_template" end it "should create a TemplateWrapper when called" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.expects(:new).returns(tw) - @scope.function_inline_template("test") + @scope.function_inline_template(["test"]) end it "should pass the template string to TemplateWrapper.result" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) tw.expects(:result).with("test") - @scope.function_inline_template("test") + @scope.function_inline_template(["test"]) end it "should return what TemplateWrapper.result returns" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) tw.expects(:result).returns("template contents evaluated") - @scope.function_inline_template("test").should == "template contents evaluated" + @scope.function_inline_template(["test"]).should == "template contents evaluated" end it "should concatenate template wrapper outputs for multiple templates" do tw1 = stub_everything "template_wrapper1" tw2 = stub_everything "template_wrapper2" Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2) tw1.stubs(:result).returns("result1") tw2.stubs(:result).returns("result2") @scope.function_inline_template(["1","2"]).should == "result1result2" end it "should raise an error if the template raises an error" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) tw.stubs(:result).raises - lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError) + lambda { @scope.function_inline_template(["1"]) }.should raise_error(Puppet::ParseError) end end diff --git a/spec/unit/parser/functions/search_spec.rb b/spec/unit/parser/functions/search_spec.rb new file mode 100755 index 000000000..fefb71425 --- /dev/null +++ b/spec/unit/parser/functions/search_spec.rb @@ -0,0 +1,21 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +describe "the 'search' function" do + before :all do + Puppet::Parser::Functions.autoloader.loadall + end + + let :scope do Puppet::Parser::Scope.new end + + it "should exist" do + Puppet::Parser::Functions.function("search").should == "function_search" + end + + it "should invoke #add_namespace on the scope for all inputs" do + scope.expects(:add_namespace).with("where") + scope.expects(:add_namespace).with("what") + scope.expects(:add_namespace).with("who") + scope.function_search(["where", "what", "who"]) + end +end diff --git a/spec/unit/parser/functions/shellquote_spec.rb b/spec/unit/parser/functions/shellquote_spec.rb index bfa2969ea..a06840b9e 100755 --- a/spec/unit/parser/functions/shellquote_spec.rb +++ b/spec/unit/parser/functions/shellquote_spec.rb @@ -1,83 +1,69 @@ #!/usr/bin/env rspec require 'spec_helper' describe "the shellquote function" do before :all do Puppet::Parser::Functions.autoloader.loadall end - before :each do - @scope = Puppet::Parser::Scope.new - end + let :scope do Puppet::Parser::Scope.new end it "should exist" do Puppet::Parser::Functions.function("shellquote").should == "function_shellquote" end - it "should handle no arguments" do - result = @scope.function_shellquote([]) - result.should(eql("")) + scope.function_shellquote([]).should == "" end it "should handle several simple arguments" do - result = @scope.function_shellquote( ['foo', 'bar@example.com', 'localhost:/dev/null', 'xyzzy+-4711,23']) - result.should(eql( 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23')) + scope.function_shellquote( + ['foo', 'bar@example.com', 'localhost:/dev/null', 'xyzzy+-4711,23'] + ).should == 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23' end it "should handle array arguments" do - - result = @scope.function_shellquote( - + scope.function_shellquote( ['foo', ['bar@example.com', 'localhost:/dev/null'], - - 'xyzzy+-4711,23']) - result.should(eql( - 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23')) + 'xyzzy+-4711,23'] + ).should == 'foo bar@example.com localhost:/dev/null xyzzy+-4711,23' end it "should quote unsafe characters" do - result = @scope.function_shellquote( ['/etc/passwd ', '(ls)', '*', '[?]', "'&'"]) - result.should(eql( '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"')) + scope.function_shellquote(['/etc/passwd ', '(ls)', '*', '[?]', "'&'"]). + should == '"/etc/passwd " "(ls)" "*" "[?]" "\'&\'"' end it "should deal with double quotes" do - result = @scope.function_shellquote( - ['"foo"bar"']) - result.should(eql( - '\'"foo"bar"\'')) + scope.function_shellquote(['"foo"bar"']).should == '\'"foo"bar"\'' end it "should cope with dollar signs" do - result = @scope.function_shellquote( ['$PATH', 'foo$bar', '"x$"']) - result.should(eql( "'$PATH' 'foo$bar' '\"x$\"'")) + scope.function_shellquote(['$PATH', 'foo$bar', '"x$"']). + should == "'$PATH' 'foo$bar' '\"x$\"'" end - it "should deal with apostrophes (single quotes)", :'fails_on_ruby_1.9.2' => true do - result = @scope.function_shellquote( - ["'foo'bar'", "`$'EDITOR'`"]) - result.should(eql( - '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"')) + it "should deal with apostrophes (single quotes)" do + scope.function_shellquote(["'foo'bar'", "`$'EDITOR'`"]). + should == '"\'foo\'bar\'" "\\`\\$\'EDITOR\'\\`"' end it "should cope with grave accents (backquotes)" do - result = @scope.function_shellquote( ['`echo *`', '`ls "$MAILPATH"`']) - result.should(eql( "'`echo *`' '`ls \"$MAILPATH\"`'")) + scope.function_shellquote(['`echo *`', '`ls "$MAILPATH"`']). + should == "'`echo *`' '`ls \"$MAILPATH\"`'" end - it "should deal with both single and double quotes", :'fails_on_ruby_1.9.2' => true do - result = @scope.function_shellquote( ['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"']) - result.should(eql( '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""')) + it "should deal with both single and double quotes" do + scope.function_shellquote(['\'foo"bar"xyzzy\'', '"foo\'bar\'xyzzy"']). + should == '"\'foo\\"bar\\"xyzzy\'" "\\"foo\'bar\'xyzzy\\""' end - it "should handle multiple quotes *and* dollars and backquotes", :'fails_on_ruby_1.9.2' => true do - result = @scope.function_shellquote( ['\'foo"$x`bar`"xyzzy\'']) - result.should(eql( '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"')) + it "should handle multiple quotes *and* dollars and backquotes" do + scope.function_shellquote(['\'foo"$x`bar`"xyzzy\'']). + should == '"\'foo\\"\\$x\\`bar\\`\\"xyzzy\'"' end it "should handle linefeeds" do - result = @scope.function_shellquote( ["foo \n bar"]) - result.should(eql( "\"foo \n bar\"")) + scope.function_shellquote(["foo \n bar"]).should == "\"foo \n bar\"" end - end diff --git a/spec/unit/parser/functions/template_spec.rb b/spec/unit/parser/functions/template_spec.rb index 6bce69534..0c8ebbd00 100755 --- a/spec/unit/parser/functions/template_spec.rb +++ b/spec/unit/parser/functions/template_spec.rb @@ -1,64 +1,97 @@ #!/usr/bin/env rspec require 'spec_helper' -describe "the template function", :'fails_on_ruby_1.9.2' => true do +describe "the template function" do before :all do Puppet::Parser::Functions.autoloader.loadall end - before :each do - @scope = Puppet::Parser::Scope.new - end + let :scope do Puppet::Parser::Scope.new end it "should exist" do Puppet::Parser::Functions.function("template").should == "function_template" end it "should create a TemplateWrapper when called" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.expects(:new).returns(tw) - @scope.function_template("test") + scope.function_template(["test"]) end it "should give the template filename to the TemplateWrapper" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) tw.expects(:file=).with("test") - @scope.function_template("test") + scope.function_template(["test"]) end it "should return what TemplateWrapper.result returns" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) tw.stubs(:file=).with("test") tw.expects(:result).returns("template contents evaluated") - @scope.function_template("test").should == "template contents evaluated" + scope.function_template(["test"]).should == "template contents evaluated" end it "should concatenate template wrapper outputs for multiple templates" do tw1 = stub_everything "template_wrapper1" tw2 = stub_everything "template_wrapper2" Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2) tw1.stubs(:file=).with("1") tw2.stubs(:file=).with("2") tw1.stubs(:result).returns("result1") tw2.stubs(:result).returns("result2") - @scope.function_template(["1","2"]).should == "result1result2" + scope.function_template(["1","2"]).should == "result1result2" end it "should raise an error if the template raises an error" do tw = stub_everything 'template_wrapper' Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw) tw.stubs(:result).raises - lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError) + expect { scope.function_template(["1"]) }.should raise_error(Puppet::ParseError) + end + + def eval_template(content, *rest) + File.stubs(:read).with("template").returns(content) + Puppet::Parser::Files.stubs(:find_template).returns("template") + scope.compiler.stubs(:environment).returns("production") + scope.function_template(['template'] + rest) + end + + it "should handle legacy template variable access correctly" do + expect { eval_template("template <%= deprecated %>") }. + to raise_error Puppet::ParseError + end + + it "should get values from the scope correctly" do + scope["deprecated"] = "deprecated value" + eval_template("template <%= deprecated %>").should == "template deprecated value" + end + + it "should handle kernel shadows without raising" do + expect { eval_template("<%= binding %>") }.should_not raise_error end + it "should not see scopes" do + scope['myvar'] = 'this is yayness' + expect { eval_template("<%= lookupvar('myvar') %>") }. + to raise_error Puppet::ParseError + end + + { "" => "", false => "false", true => "true" }.each do |input, output| + it "should support defined variables (#{input.inspect} => #{output.inspect})" do + scope['yayness'] = input + expect { + eval_template("<%= @yayness %>").should == output + }.should_not raise_error + end + end end diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb index 805e287af..ad232d26a 100755 --- a/spec/unit/parser/parser_spec.rb +++ b/spec/unit/parser/parser_spec.rb @@ -1,452 +1,520 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Parser do Puppet::Parser::AST before :each do @known_resource_types = Puppet::Resource::TypeCollection.new("development") @parser = Puppet::Parser::Parser.new "development" @parser.stubs(:known_resource_types).returns @known_resource_types @true_ast = Puppet::Parser::AST::Boolean.new :value => true end it "should require an environment at initialization" do - lambda { Puppet::Parser::Parser.new }.should raise_error(ArgumentError) + expect { Puppet::Parser::Parser.new }.should raise_error(ArgumentError) end it "should set the environment" do env = Puppet::Node::Environment.new Puppet::Parser::Parser.new(env).environment.should == env end it "should convert the environment into an environment instance if a string is provided" do env = Puppet::Node::Environment.new("testing") Puppet::Parser::Parser.new("testing").environment.should == env end it "should be able to look up the environment-specific resource type collection" do rtc = Puppet::Node::Environment.new("development").known_resource_types parser = Puppet::Parser::Parser.new "development" parser.known_resource_types.should equal(rtc) end - it "should delegate importing to the known resource type loader" do - parser = Puppet::Parser::Parser.new "development" - parser.known_resource_types.loader.expects(:import).with("newfile", "current_file") - parser.lexer.expects(:file).returns "current_file" - parser.import("newfile") + context "when importing" do + it "should delegate importing to the known resource type loader" do + parser = Puppet::Parser::Parser.new "development" + parser.known_resource_types.loader.expects(:import).with("newfile", "current_file") + parser.lexer.expects(:file).returns "current_file" + parser.import("newfile") + end + + it "should import multiple files on one line" do + @parser.known_resource_types.loader.expects(:import).with('one', nil) + @parser.known_resource_types.loader.expects(:import).with('two', nil) + @parser.parse("import 'one', 'two'") + end end describe "when parsing files" do before do FileTest.stubs(:exist?).returns true File.stubs(:read).returns "" @parser.stubs(:watch_file) end it "should treat files ending in 'rb' as ruby files" do @parser.expects(:parse_ruby_file) @parser.file = "/my/file.rb" @parser.parse end end describe "when parsing append operator" do it "should not raise syntax errors" do - lambda { @parser.parse("$var += something") }.should_not raise_error + expect { @parser.parse("$var += something") }.should_not raise_error end it "shouldraise syntax error on incomplete syntax " do - lambda { @parser.parse("$var += ") }.should raise_error + expect { @parser.parse("$var += ") }.should raise_error end it "should create ast::VarDef with append=true" do vardef = @parser.parse("$var += 2").code[0] vardef.should be_a(Puppet::Parser::AST::VarDef) vardef.append.should == true end it "should work with arrays too" do vardef = @parser.parse("$var += ['test']").code[0] vardef.should be_a(Puppet::Parser::AST::VarDef) vardef.append.should == true end end describe "when parsing selector" do it "should support hash access on the left hand side" do - lambda { @parser.parse("$h = { 'a' => 'b' } $a = $h['a'] ? { 'b' => 'd', default => undef }") }.should_not raise_error + expect { @parser.parse("$h = { 'a' => 'b' } $a = $h['a'] ? { 'b' => 'd', default => undef }") }.should_not raise_error end end describe "parsing 'unless'" do it "should create the correct ast objects" do Puppet::Parser::AST::Not.expects(:new).with { |h| h[:value].is_a?(Puppet::Parser::AST::Boolean) } @parser.parse("unless false { $var = 1 }") end it "should not raise an error with empty statements" do - lambda { @parser.parse("unless false { }") }.should_not raise_error + expect { @parser.parse("unless false { }") }.should_not raise_error end #test for bug #13296 it "should not override 'unless' as a parameter inside resources" do lambda { @parser.parse("exec {'/bin/echo foo': unless => '/usr/bin/false',}") }.should_not raise_error end end describe "when parsing parameter names" do Puppet::Parser::Lexer::KEYWORDS.sort_tokens.each do |keyword| it "should allow #{keyword} as a keyword" do lambda { @parser.parse("exec {'/bin/echo foo': #{keyword} => '/usr/bin/false',}") }.should_not raise_error end end end describe "when parsing 'if'" do it "not, it should create the correct ast objects" do Puppet::Parser::AST::Not.expects(:new).with { |h| h[:value].is_a?(Puppet::Parser::AST::Boolean) } @parser.parse("if ! true { $var = 1 }") end it "boolean operation, it should create the correct ast objects" do Puppet::Parser::AST::BooleanOperator.expects(:new).with { |h| h[:rval].is_a?(Puppet::Parser::AST::Boolean) and h[:lval].is_a?(Puppet::Parser::AST::Boolean) and h[:operator]=="or" } @parser.parse("if true or true { $var = 1 }") end it "comparison operation, it should create the correct ast objects" do Puppet::Parser::AST::ComparisonOperator.expects(:new).with { |h| h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="<" } @parser.parse("if 1 < 2 { $var = 1 }") end end describe "when parsing if complex expressions" do it "should create a correct ast tree" do aststub = stub_everything 'ast' Puppet::Parser::AST::ComparisonOperator.expects(:new).with { |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]==">" }.returns(aststub) Puppet::Parser::AST::ComparisonOperator.expects(:new).with { |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="==" }.returns(aststub) Puppet::Parser::AST::BooleanOperator.expects(:new).with { |h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and" } @parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }") end it "should raise an error on incorrect expression" do - lambda { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error + expect { @parser.parse("if (1 > 2 > ) or (1 == 2) { $var = 1 }") }.should raise_error end end describe "when parsing resource references" do it "should not raise syntax errors" do - lambda { @parser.parse('exec { test: param => File["a"] }') }.should_not raise_error + expect { @parser.parse('exec { test: param => File["a"] }') }.should_not raise_error end it "should not raise syntax errors with multiple references" do - lambda { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error + expect { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error end it "should create an ast::ResourceReference" do Puppet::Parser::AST::ResourceReference.expects(:new).with { |arg| arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(Puppet::Parser::AST::ASTArray) } @parser.parse('exec { test: command => File["a","b"] }') end end describe "when parsing resource overrides" do it "should not raise syntax errors" do - lambda { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error + expect { @parser.parse('Resource["title"] { param => value }') }.should_not raise_error end it "should not raise syntax errors with multiple overrides" do - lambda { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error + expect { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error end it "should create an ast::ResourceOverride" do #Puppet::Parser::AST::ResourceOverride.expects(:new).with { |arg| # arg[:line]==1 and arg[:object].is_a?(Puppet::Parser::AST::ResourceReference) and arg[:parameters].is_a?(Puppet::Parser::AST::ResourceParam) #} ro = @parser.parse('Resource["title1","title2"] { param => value }').code[0] ro.should be_a(Puppet::Parser::AST::ResourceOverride) ro.line.should == 1 ro.object.should be_a(Puppet::Parser::AST::ResourceReference) ro.parameters[0].should be_a(Puppet::Parser::AST::ResourceParam) end end describe "when parsing if statements" do it "should not raise errors with empty if" do - lambda { @parser.parse("if true { }") }.should_not raise_error + expect { @parser.parse("if true { }") }.should_not raise_error end it "should not raise errors with empty else" do - lambda { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error + expect { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error end it "should not raise errors with empty if and else" do - lambda { @parser.parse("if false { } else { }") }.should_not raise_error + expect { @parser.parse("if false { } else { }") }.should_not raise_error end it "should create a nop node for empty branch" do Puppet::Parser::AST::Nop.expects(:new) @parser.parse("if true { }") end it "should create a nop node for empty else branch" do Puppet::Parser::AST::Nop.expects(:new) @parser.parse("if true { notice('test') } else { }") end it "should build a chain of 'ifs' if there's an 'elsif'" do - lambda { @parser.parse(<<-PP) }.should_not raise_error + expect { @parser.parse(<<-PP) }.should_not raise_error if true { notice('test') } elsif true {} else { } PP end end describe "when parsing function calls" do - it "should not raise errors with no arguments" do - lambda { @parser.parse("tag()") }.should_not raise_error + expect { @parser.parse("tag()") }.should_not raise_error end it "should not raise errors with rvalue function with no args" do - lambda { @parser.parse("$a = template()") }.should_not raise_error + expect { @parser.parse("$a = template()") }.should_not raise_error end it "should not raise errors with arguments" do - lambda { @parser.parse("notice(1)") }.should_not raise_error + expect { @parser.parse("notice(1)") }.should_not raise_error end it "should not raise errors with multiple arguments" do - lambda { @parser.parse("notice(1,2)") }.should_not raise_error + expect { @parser.parse("notice(1,2)") }.should_not raise_error end it "should not raise errors with multiple arguments and a trailing comma" do - lambda { @parser.parse("notice(1,2,)") }.should_not raise_error + expect { @parser.parse("notice(1,2,)") }.should_not raise_error end end - describe "when parsing arrays with trailing comma" do + describe "when parsing arrays" do + it "should parse an array" do + expect { @parser.parse("$a = [1,2]") }.should_not raise_error + end it "should not raise errors with a trailing comma" do - lambda { @parser.parse("$a = [1,2,]") }.should_not raise_error + expect { @parser.parse("$a = [1,2,]") }.should_not raise_error + end + + it "should accept an empty array" do + expect { @parser.parse("$var = []\n") }.should_not raise_error end end describe "when providing AST context" do before do @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev" @parser.stubs(:lexer).returns @lexer end it "should include the lexer's line" do @parser.ast_context[:line].should == 50 end it "should include the lexer's file" do @parser.ast_context[:file].should == "/foo/bar" end it "should include the docs if directed to do so" do @parser.ast_context(true)[:doc].should == "whev" end it "should not include the docs when told not to" do @parser.ast_context(false)[:doc].should be_nil end it "should not include the docs by default" do @parser.ast_context[:doc].should be_nil end end describe "when building ast nodes" do before do @lexer = stub 'lexer', :line => 50, :file => "/foo/bar", :getcomment => "whev" @parser.stubs(:lexer).returns @lexer @class = Puppet::Resource::Type.new(:hostclass, "myclass", :use_docs => false) end it "should return a new instance of the provided class created with the provided options" do @class.expects(:new).with { |opts| opts[:foo] == "bar" } @parser.ast(@class, :foo => "bar") end it "should merge the ast context into the provided options" do @class.expects(:new).with { |opts| opts[:file] == "/foo" } @parser.expects(:ast_context).returns :file => "/foo" @parser.ast(@class, :foo => "bar") end it "should prefer provided options over AST context" do @class.expects(:new).with { |opts| opts[:file] == "/bar" } @lexer.expects(:file).returns "/foo" @parser.ast(@class, :file => "/bar") end it "should include docs when the AST class uses them" do @class.expects(:use_docs).returns true @class.stubs(:new) @parser.expects(:ast_context).with{ |docs, line| docs == true }.returns({}) @parser.ast(@class, :file => "/bar") end it "should get docs from lexer using the correct AST line number" do @class.expects(:use_docs).returns true @class.stubs(:new).with{ |a| a[:doc] == "doc" } @lexer.expects(:getcomment).with(12).returns "doc" @parser.ast(@class, :file => "/bar", :line => 12) end end describe "when retrieving a specific node" do it "should delegate to the known_resource_types node" do @known_resource_types.expects(:node).with("node") @parser.node("node") end end describe "when retrieving a specific class" do it "should delegate to the loaded code" do @known_resource_types.expects(:hostclass).with("class") @parser.hostclass("class") end end describe "when retrieving a specific definitions" do it "should delegate to the loaded code" do @known_resource_types.expects(:definition).with("define") @parser.definition("define") end end describe "when determining the configuration version" do it "should determine it from the resource type collection" do @parser.known_resource_types.expects(:version).returns "foo" @parser.version.should == "foo" end end describe "when looking up definitions" do it "should use the known resource types to check for them by name" do @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:definition).returns(:this_value) @parser.find_definition("namespace","name").should == :this_value end end describe "when looking up hostclasses" do it "should use the known resource types to check for them by name" do @parser.known_resource_types.stubs(:find_or_load).with("namespace","name",:hostclass).returns(:this_value) @parser.find_hostclass("namespace","name").should == :this_value end end describe "when parsing classes" do before :each do @krt = Puppet::Resource::TypeCollection.new("development") @parser = Puppet::Parser::Parser.new "development" @parser.stubs(:known_resource_types).returns @krt end it "should not create new classes" do @parser.parse("class foobar {}").code[0].should be_a(Puppet::Parser::AST::Hostclass) @krt.hostclass("foobar").should be_nil end it "should correctly set the parent class when one is provided" do @parser.parse("class foobar inherits yayness {}").code[0].instantiate('')[0].parent.should == "yayness" end it "should correctly set the parent class for multiple classes at a time" do statements = @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}").code statements[0].instantiate('')[0].parent.should == "yayness" statements[1].instantiate('')[0].parent.should == "bar" end it "should define the code when some is provided" do @parser.parse("class foobar { $var = val }").code[0].code.should_not be_nil end + it "should accept parameters with trailing comma" do + @parser.parse("file { '/example': ensure => file, }").should be + end + it "should accept parametrized classes with trailing comma" do @parser.parse("class foobar ($var1 = 0,) { $var = val }").code[0].code.should_not be_nil end it "should define parameters when provided" do foobar = @parser.parse("class foobar($biz,$baz) {}").code[0].instantiate('')[0] foobar.arguments.should == {"biz" => nil, "baz" => nil} end end describe "when parsing resources" do before :each do @krt = Puppet::Resource::TypeCollection.new("development") @parser = Puppet::Parser::Parser.new "development" @parser.stubs(:known_resource_types).returns @krt end it "should be able to parse class resources" do @krt.add(Puppet::Resource::Type.new(:hostclass, "foobar", :arguments => {"biz" => nil})) - lambda { @parser.parse("class { foobar: biz => stuff }") }.should_not raise_error + expect { @parser.parse("class { foobar: biz => stuff }") }.should_not raise_error end it "should correctly mark exported resources as exported" do @parser.parse("@@file { '/file': }").code[0].exported.should be_true end it "should correctly mark virtual resources as virtual" do @parser.parse("@file { '/file': }").code[0].virtual.should be_true end end describe "when parsing nodes" do it "should be able to parse a node with a single name" do node = @parser.parse("node foo { }").code[0] node.should be_a Puppet::Parser::AST::Node node.names.length.should == 1 node.names[0].value.should == "foo" end it "should be able to parse a node with two names" do node = @parser.parse("node foo, bar { }").code[0] node.should be_a Puppet::Parser::AST::Node node.names.length.should == 2 node.names[0].value.should == "foo" node.names[1].value.should == "bar" end it "should be able to parse a node with three names" do node = @parser.parse("node foo, bar, baz { }").code[0] node.should be_a Puppet::Parser::AST::Node node.names.length.should == 3 node.names[0].value.should == "foo" node.names[1].value.should == "bar" node.names[2].value.should == "baz" end end + + it "should fail if trying to collect defaults" do + expect { @parser.parse("@Port { protocols => tcp }") }. + to raise_error Puppet::ParseError + end + + context "when parsing collections" do + it "should parse basic collections" do + @parser.parse("Port <| |>").code. + should be_all {|x| x.is_a? Puppet::Parser::AST::Collection } + end + + it "should parse fully qualified collections" do + @parser.parse("Port::Range <| |>").code. + should be_all {|x| x.is_a? Puppet::Parser::AST::Collection } + end + end + + it "should not assign to a fully qualified variable" do + expect { @parser.parse("$one::two = yay") }.to raise_error Puppet::ParseError + end + + it "should parse assignment of undef" do + tree = @parser.parse("$var = undef") + tree.code.children[0].should be_an_instance_of Puppet::Parser::AST::VarDef + tree.code.children[0].value.should be_an_instance_of Puppet::Parser::AST::Undef + end + + context "#namesplit" do + { "base::sub" => %w{base sub}, + "main" => ["", "main"], + "one::two::three::four" => ["one::two::three", "four"], + }.each do |input, output| + it "should split #{input.inspect} to #{output.inspect}" do + @parser.namesplit(input).should == output + end + end + end + + it "should treat classes as case insensitive" do + @parser.known_resource_types.import_ast(@parser.parse("class yayness {}"), '') + @parser.known_resource_types.hostclass('yayness'). + should == @parser.find_hostclass("", "YayNess") + end + + it "should treat defines as case insensitive" do + @parser.known_resource_types.import_ast(@parser.parse("define funtest {}"), '') + @parser.known_resource_types.hostclass('funtest'). + should == @parser.find_hostclass("", "fUntEst") + end end diff --git a/spec/unit/parser/resource_spec.rb b/spec/unit/parser/resource_spec.rb index 508159f45..59513a103 100755 --- a/spec/unit/parser/resource_spec.rb +++ b/spec/unit/parser/resource_spec.rb @@ -1,639 +1,640 @@ #!/usr/bin/env rspec require 'spec_helper' # LAK: FIXME This is just new tests for resources; I have # not moved all tests over yet. describe Puppet::Parser::Resource do before do @node = Puppet::Node.new("yaynode") @known_resource_types = Puppet::Resource::TypeCollection.new("env") @compiler = Puppet::Parser::Compiler.new(@node) @compiler.environment.stubs(:known_resource_types).returns @known_resource_types @source = newclass "" @scope = @compiler.topscope end def mkresource(args = {}) args[:source] ||= @source args[:scope] ||= @scope params = args[:parameters] || {:one => "yay", :three => "rah"} if args[:parameters] == :none args.delete(:parameters) elsif not args[:parameters].is_a? Array args[:parameters] = paramify(args[:source], params) end Puppet::Parser::Resource.new("resource", "testing", args) end def param(name, value, source) Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source) end def paramify(source, hash) hash.collect do |name, value| Puppet::Parser::Resource::Param.new( :name => name, :value => value, :source => source ) end end def newclass(name) @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name) end def newdefine(name) @known_resource_types.add Puppet::Resource::Type.new(:definition, name) end def newnode(name) @known_resource_types.add Puppet::Resource::Type.new(:node, name) end it "should use the file lookup module" do Puppet::Parser::Resource.ancestors.should be_include(Puppet::FileCollection::Lookup) end it "should get its environment from its scope" do scope = stub 'scope', :source => stub("source"), :namespaces => nil scope.expects(:environment).returns("foo").at_least_once Puppet::Parser::Resource.new("file", "whatever", :scope => scope).environment.should == "foo" end it "should use the resource type collection helper module" do Puppet::Parser::Resource.ancestors.should be_include(Puppet::Resource::TypeCollectionHelper) end it "should use the scope's environment as its environment" do @scope.expects(:environment).returns("myenv").at_least_once Puppet::Parser::Resource.new("file", "whatever", :scope => @scope).environment.should == "myenv" end it "should be isomorphic if it is builtin and models an isomorphic type" do Puppet::Type.type(:file).expects(:isomorphic?).returns(true) @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true end it "should not be isomorphic if it is builtin and models a non-isomorphic type" do Puppet::Type.type(:file).expects(:isomorphic?).returns(false) @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false end it "should be isomorphic if it is not builtin" do newdefine "whatever" @resource = Puppet::Parser::Resource.new("whatever", "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true end it "should have a array-indexing method for retrieving parameter values" do @resource = mkresource @resource[:one].should == "yay" end it "should use a Puppet::Resource for converting to a ral resource" do trans = mock 'resource', :to_ral => "yay" @resource = mkresource @resource.expects(:to_resource).returns trans @resource.to_ral.should == "yay" end it "should be able to use the indexing operator to access parameters" do resource = Puppet::Parser::Resource.new("resource", "testing", :source => "source", :scope => @scope) resource["foo"] = "bar" resource["foo"].should == "bar" end it "should return the title when asked for a parameter named 'title'" do Puppet::Parser::Resource.new("resource", "testing", :source => @source, :scope => @scope)[:title].should == "testing" end describe "when initializing" do before do @arguments = {:scope => @scope} end - it "should fail unless #{name.to_s} is specified", :'fails_on_ruby_1.9.2' => true do - lambda { Puppet::Parser::Resource.new('file', '/my/file') }.should raise_error(ArgumentError) + it "should fail unless #{name.to_s} is specified" do + expect { Puppet::Parser::Resource.new('file', '/my/file') }. + should raise_error(ArgumentError) end it "should set the reference correctly" do res = Puppet::Parser::Resource.new("resource", "testing", @arguments) res.ref.should == "Resource[testing]" end it "should be tagged with user tags" do tags = [ "tag1", "tag2" ] @arguments[:parameters] = [ param(:tag, tags , :source) ] res = Puppet::Parser::Resource.new("resource", "testing", @arguments) (res.tags & tags).should == tags end end describe "when evaluating" do before do @node = Puppet::Node.new "test-node" @compiler = Puppet::Parser::Compiler.new @node @catalog = Puppet::Resource::Catalog.new source = stub('source') source.stubs(:module_name) @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => source) @catalog.add_resource(Puppet::Parser::Resource.new("stage", :main, :scope => @scope)) end it "should evaluate the associated AST definition" do definition = newdefine "mydefine" res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source, :catalog => @catalog) definition.expects(:evaluate_code).with(res) res.evaluate end it "should evaluate the associated AST class" do @class = newclass "myclass" res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source, :catalog => @catalog) @class.expects(:evaluate_code).with(res) res.evaluate end it "should evaluate the associated AST node" do nodedef = newnode("mynode") res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source, :catalog => @catalog) nodedef.expects(:evaluate_code).with(res) res.evaluate end - it "should add an edge to any specified stage for class resources", :'fails_on_ruby_1.9.2' => true do - @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '') + it "should add an edge to any specified stage for class resources" do + @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", {}) other_stage = Puppet::Parser::Resource.new(:stage, "other", :scope => @scope, :catalog => @catalog) @compiler.add_resource(@scope, other_stage) resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog) resource[:stage] = 'other' @compiler.add_resource(@scope, resource) resource.evaluate @compiler.catalog.edge?(other_stage, resource).should be_true end - it "should fail if an unknown stage is specified", :'fails_on_ruby_1.9.2' => true do - @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '') + it "should fail if an unknown stage is specified" do + @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", {}) resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog) resource[:stage] = 'other' lambda { resource.evaluate }.should raise_error(ArgumentError, /Could not find stage other specified by/) end - it "should add edges from the class resources to the parent's stage if no stage is specified", :'fails_on_ruby_1.9.2' => true do + it "should add edges from the class resources to the parent's stage if no stage is specified" do main = @compiler.catalog.resource(:stage, :main) foo_stage = Puppet::Parser::Resource.new(:stage, :foo_stage, :scope => @scope, :catalog => @catalog) @compiler.add_resource(@scope, foo_stage) - @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '') + @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", {}) resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog) resource[:stage] = 'foo_stage' @compiler.add_resource(@scope, resource) resource.evaluate @compiler.catalog.should be_edge(foo_stage, resource) end it "should allow edges to propagate multiple levels down the scope hierarchy" do Puppet[:code] = <<-MANIFEST stage { before: before => Stage[main] } class alpha { include beta } class beta { include gamma } class gamma { } class { alpha: stage => before } MANIFEST catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new 'anyone') # Stringify them to make for easier lookup edges = catalog.edges.map {|e| [e.source.ref, e.target.ref]} edges.should include(["Stage[before]", "Class[Alpha]"]) edges.should include(["Stage[before]", "Class[Beta]"]) edges.should include(["Stage[before]", "Class[Gamma]"]) end it "should use the specified stage even if the parent scope specifies one" do Puppet[:code] = <<-MANIFEST stage { before: before => Stage[main], } stage { after: require => Stage[main], } class alpha { class { beta: stage => after } } class beta { } class { alpha: stage => before } MANIFEST catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new 'anyone') edges = catalog.edges.map {|e| [e.source.ref, e.target.ref]} edges.should include(["Stage[before]", "Class[Alpha]"]) edges.should include(["Stage[after]", "Class[Beta]"]) end - it "should add edges from top-level class resources to the main stage if no stage is specified", :'fails_on_ruby_1.9.2' => true do + it "should add edges from top-level class resources to the main stage if no stage is specified" do main = @compiler.catalog.resource(:stage, :main) - @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '') + @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", {}) resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog) @compiler.add_resource(@scope, resource) resource.evaluate @compiler.catalog.should be_edge(main, resource) end end describe "when finishing" do before do @class = newclass "myclass" @nodedef = newnode("mynode") @resource = Puppet::Parser::Resource.new("file", "whatever", :scope => @scope, :source => @source) end it "should do nothing if it has already been finished" do @resource.finish @resource.expects(:add_metaparams).never @resource.finish end it "should add all defaults available from the scope" do @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source)) @resource.finish @resource[:owner].should == "default" end it "should not replace existing parameters with defaults" do @resource.set_parameter :owner, "oldvalue" @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced) @resource.finish @resource[:owner].should == "oldvalue" end it "should add a copy of each default, rather than the actual default parameter instance" do newparam = param(:owner, "default", @resource.source) other = newparam.dup other.value = "other" newparam.expects(:dup).returns(other) @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam) @resource.finish @resource[:owner].should == "other" end it "should be running in metaparam compatibility mode if running a version below 0.25" do catalog = stub 'catalog', :client_version => "0.24.8" @resource.stubs(:catalog).returns catalog @resource.should be_metaparam_compatibility_mode end it "should be running in metaparam compatibility mode if running no client version is available" do catalog = stub 'catalog', :client_version => nil @resource.stubs(:catalog).returns catalog @resource.should be_metaparam_compatibility_mode end it "should not be running in metaparam compatibility mode if running a version at or above 0.25" do catalog = stub 'catalog', :client_version => "0.25.0" @resource.stubs(:catalog).returns catalog @resource.should_not be_metaparam_compatibility_mode end it "should not copy relationship metaparams when not in metaparam compatibility mode" do @scope['require'] = "bar" @resource.stubs(:metaparam_compatibility_mode?).returns false @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["require"].should be_nil end it "should copy relationship metaparams when in metaparam compatibility mode" do @scope['require'] = "bar" @resource.stubs(:metaparam_compatibility_mode?).returns true @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["require"].should == "bar" end it "should stack relationship metaparams when in metaparam compatibility mode" do @resource.set_parameter("require", "foo") @scope['require'] = "bar" @resource.stubs(:metaparam_compatibility_mode?).returns true @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["require"].should == ["foo", "bar"] end end describe "when being tagged" do before do @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo} @scope.stubs(:resource).returns @scope_resource @resource = Puppet::Parser::Resource.new("file", "yay", :scope => @scope, :source => mock('source')) end it "should get tagged with the resource type" do @resource.tags.should be_include("file") end it "should get tagged with the title" do @resource.tags.should be_include("yay") end it "should get tagged with each name in the title if the title is a qualified class name" do resource = Puppet::Parser::Resource.new("file", "one::two", :scope => @scope, :source => mock('source')) resource.tags.should be_include("one") resource.tags.should be_include("two") end it "should get tagged with each name in the type if the type is a qualified class name" do resource = Puppet::Parser::Resource.new("one::two", "whatever", :scope => @scope, :source => mock('source')) resource.tags.should be_include("one") resource.tags.should be_include("two") end it "should not get tagged with non-alphanumeric titles" do resource = Puppet::Parser::Resource.new("file", "this is a test", :scope => @scope, :source => mock('source')) resource.tags.should_not be_include("this is a test") end it "should fail on tags containing '*' characters" do lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError) end it "should fail on tags starting with '-' characters" do lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError) end it "should fail on tags containing ' ' characters" do lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError) end it "should allow alpha tags" do lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError) end end describe "when merging overrides" do before do @source = "source1" @resource = mkresource :source => @source @override = mkresource :source => @source end it "should fail when the override was not created by a parent class" do @override.source = "source2" @override.source.expects(:child_of?).with("source1").returns(false) lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError) end it "should succeed when the override was created in the current scope" do @resource.source = "source3" @override.source = @resource.source @override.source.expects(:child_of?).with("source3").never params = {:a => :b, :c => :d} @override.expects(:parameters).returns(params) @resource.expects(:override_parameter).with(:b) @resource.expects(:override_parameter).with(:d) @resource.merge(@override) end it "should succeed when a parent class created the override" do @resource.source = "source3" @override.source = "source4" @override.source.expects(:child_of?).with("source3").returns(true) params = {:a => :b, :c => :d} @override.expects(:parameters).returns(params) @resource.expects(:override_parameter).with(:b) @resource.expects(:override_parameter).with(:d) @resource.merge(@override) end it "should add new parameters when the parameter is not set" do @source.stubs(:child_of?).returns true @override.set_parameter(:testing, "value") @resource.merge(@override) @resource[:testing].should == "value" end it "should replace existing parameter values" do @source.stubs(:child_of?).returns true @resource.set_parameter(:testing, "old") @override.set_parameter(:testing, "value") @resource.merge(@override) @resource[:testing].should == "value" end it "should add values to the parameter when the override was created with the '+>' syntax" do @source.stubs(:child_of?).returns true param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source) param.add = true @override.set_parameter(param) @resource.set_parameter(:testing, "other") @resource.merge(@override) @resource[:testing].should == %w{other testing} end it "should not merge parameter values when multiple resources are overriden with '+>' at once " do @resource_2 = mkresource :source => @source @resource. set_parameter(:testing, "old_val_1") @resource_2.set_parameter(:testing, "old_val_2") @source.stubs(:child_of?).returns true param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "new_val", :source => @resource.source) param.add = true @override.set_parameter(param) @resource. merge(@override) @resource_2.merge(@override) @resource [:testing].should == %w{old_val_1 new_val} @resource_2[:testing].should == %w{old_val_2 new_val} end it "should promote tag overrides to real tags" do @source.stubs(:child_of?).returns true param = Puppet::Parser::Resource::Param.new(:name => :tag, :value => "testing", :source => @resource.source) @override.set_parameter(param) @resource.merge(@override) @resource.tagged?("testing").should be_true end end it "should be able to be converted to a normal resource" do @source = stub 'scope', :name => "myscope" @resource = mkresource :source => @source @resource.should respond_to(:to_resource) end describe "when being converted to a resource" do before do @parser_resource = mkresource :scope => @scope, :parameters => {:foo => "bar", :fee => "fum"} end it "should create an instance of Puppet::Resource" do @parser_resource.to_resource.should be_instance_of(Puppet::Resource) end it "should set the type correctly on the Puppet::Resource" do @parser_resource.to_resource.type.should == @parser_resource.type end it "should set the title correctly on the Puppet::Resource" do @parser_resource.to_resource.title.should == @parser_resource.title end it "should copy over all of the parameters" do result = @parser_resource.to_resource.to_hash # The name will be in here, also. result[:foo].should == "bar" result[:fee].should == "fum" end it "should copy over the tags" do @parser_resource.tag "foo" @parser_resource.tag "bar" @parser_resource.to_resource.tags.should == @parser_resource.tags end it "should copy over the line" do @parser_resource.line = 40 @parser_resource.to_resource.line.should == 40 end it "should copy over the file" do @parser_resource.file = "/my/file" @parser_resource.to_resource.file.should == "/my/file" end it "should copy over the 'exported' value" do @parser_resource.exported = true @parser_resource.to_resource.exported.should be_true end it "should copy over the 'virtual' value" do @parser_resource.virtual = true @parser_resource.to_resource.virtual.should be_true end it "should convert any parser resource references to Puppet::Resource instances" do ref = Puppet::Resource.new("file", "/my/file") @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ref} result = @parser_resource.to_resource result[:fee].should == Puppet::Resource.new(:file, "/my/file") end it "should convert any parser resource references to Puppet::Resource instances even if they are in an array" do ref = Puppet::Resource.new("file", "/my/file") @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ["a", ref]} result = @parser_resource.to_resource result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file")] end it "should convert any parser resource references to Puppet::Resource instances even if they are in an array of array, and even deeper" do ref1 = Puppet::Resource.new("file", "/my/file1") ref2 = Puppet::Resource.new("file", "/my/file2") @parser_resource = mkresource :source => @source, :parameters => {:foo => "bar", :fee => ["a", [ref1,ref2]]} result = @parser_resource.to_resource result[:fee].should == ["a", Puppet::Resource.new(:file, "/my/file1"), Puppet::Resource.new(:file, "/my/file2")] end it "should fail if the same param is declared twice" do lambda do @parser_resource = mkresource :source => @source, :parameters => [ Puppet::Parser::Resource::Param.new( :name => :foo, :value => "bar", :source => @source ), Puppet::Parser::Resource::Param.new( :name => :foo, :value => "baz", :source => @source ) ] end.should raise_error(Puppet::ParseError) end end describe "when validating" do it "should check each parameter" do resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => stub("source") resource[:one] = :two resource[:three] = :four resource.expects(:validate_parameter).with(:one) resource.expects(:validate_parameter).with(:three) resource.send(:validate) end it "should raise a parse error when there's a failure" do resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => stub("source") resource[:one] = :two resource.expects(:validate_parameter).with(:one).raises ArgumentError lambda { resource.send(:validate) }.should raise_error(Puppet::ParseError) end end describe "when setting parameters" do before do @source = newclass "foobar" @resource = Puppet::Parser::Resource.new :foo, "bar", :scope => @scope, :source => @source end it "should accept Param instances and add them to the parameter list" do param = Puppet::Parser::Resource::Param.new :name => "foo", :value => "bar", :source => @source @resource.set_parameter(param) @resource["foo"].should == "bar" end it "should fail when provided a parameter name but no value" do lambda { @resource.set_parameter("myparam") }.should raise_error(ArgumentError) end it "should allow parameters to be set to 'false'" do @resource.set_parameter("myparam", false) @resource["myparam"].should be_false end it "should use its source when provided a parameter name and value" do @resource.set_parameter("myparam", "myvalue") @resource["myparam"].should == "myvalue" end end # part of #629 -- the undef keyword. Make sure 'undef' params get skipped. it "should not include 'undef' parameters when converting itself to a hash" do resource = Puppet::Parser::Resource.new "file", "/tmp/testing", :source => mock("source"), :scope => mock("scope") resource[:owner] = :undef resource[:mode] = "755" resource.to_hash[:owner].should be_nil end end diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 11146fa72..ba37ec398 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -1,534 +1,548 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Parser::Scope do before :each do @topscope = Puppet::Parser::Scope.new # This is necessary so we don't try to use the compiler to discover our parent. @topscope.parent = nil @scope = Puppet::Parser::Scope.new @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) @scope.parent = @topscope end it "should be able to store references to class scopes" do lambda { @scope.class_set "myname", "myscope" }.should_not raise_error end it "should be able to retrieve class scopes by name" do @scope.class_set "myname", "myscope" @scope.class_scope("myname").should == "myscope" end it "should be able to retrieve class scopes by object" do klass = mock 'ast_class' klass.expects(:name).returns("myname") @scope.class_set "myname", "myscope" @scope.class_scope(klass).should == "myscope" end it "should be able to retrieve its parent module name from the source of its parent type" do @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo, :module_name => "foo") @scope.parent_module_name.should == "foo" end it "should return a nil parent module name if it has no parent" do @topscope.parent_module_name.should be_nil end it "should return a nil parent module name if its parent has no source" do @scope.parent_module_name.should be_nil end it "should get its environment from its compiler" do env = Puppet::Node::Environment.new compiler = stub 'compiler', :environment => env scope = Puppet::Parser::Scope.new :compiler => compiler scope.environment.should equal(env) end it "should use the default environment if none is available" do Puppet::Parser::Scope.new.environment.should equal(Puppet::Node::Environment.new) end it "should use the resource type collection helper to find its known resource types" do Puppet::Parser::Scope.ancestors.should include(Puppet::Resource::TypeCollectionHelper) end describe "when missing methods are called" do before :each do @env = Puppet::Node::Environment.new('testing') @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new('foo', :environment => @env)) @scope = Puppet::Parser::Scope.new(:compiler => @compiler) end it "should load and call the method if it looks like a function and it exists" do @scope.function_sprintf(["%b", 123]).should == "1111011" end it "should raise NoMethodError if the method doesn't look like a function" do expect { @scope.sprintf(["%b", 123]) }.should raise_error(NoMethodError) end it "should raise NoMethodError if the method looks like a function but doesn't exist" do expect { @scope.function_fake_bs(['cows']) }.should raise_error(NoMethodError) end end describe "when initializing" do it "should extend itself with its environment's Functions module as well as the default" do env = Puppet::Node::Environment.new("myenv") root = Puppet::Node::Environment.root compiler = stub 'compiler', :environment => env scope = Puppet::Parser::Scope.new(:compiler => compiler) scope.singleton_class.ancestors.should be_include(Puppet::Parser::Functions.environment_module(env)) scope.singleton_class.ancestors.should be_include(Puppet::Parser::Functions.environment_module(root)) end it "should extend itself with the default Functions module if its environment is the default" do root = Puppet::Node::Environment.root scope = Puppet::Parser::Scope.new scope.singleton_class.ancestors.should be_include(Puppet::Parser::Functions.environment_module(root)) end it "should remember if it is dynamic" do (!!Puppet::Parser::Scope.new(:dynamic => true).dynamic).should == true end it "should assume it is not dynamic" do (!Puppet::Parser::Scope.new.dynamic).should == true end end describe "when looking up a variable" do it "should support :lookupvar and :setvar for backward compatibility" do @scope.setvar("var", "yep") @scope.lookupvar("var").should == "yep" end it "should return nil for unset variables" do @scope["var"].should be_nil end it "should be able to look up values" do @scope["var"] = "yep" @scope["var"].should == "yep" end it "should be able to look up hashes" do @scope["var"] = {"a" => "b"} @scope["var"].should == {"a" => "b"} end it "should be able to look up variables in parent scopes" do @topscope["var"] = "parentval" @scope["var"].should == "parentval" end it "should prefer its own values to parent values" do @topscope["var"] = "parentval" @scope["var"] = "childval" @scope["var"].should == "childval" end it "should be able to detect when variables are set" do @scope["var"] = "childval" @scope.should be_include("var") end it "should be able to detect when variables are not set" do @scope.should_not be_include("var") end it "should support iteration over its variables" do @scope["one"] = "two" @scope["three"] = "four" hash = {} @scope.each { |name, value| hash[name] = value } hash.should == {"one" => "two", "three" => "four" } end it "should include Enumerable" do @scope.singleton_class.ancestors.should be_include(Enumerable) end describe "and the variable is qualified" do before do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foonode")) @scope.compiler = @compiler @known_resource_types = @scope.known_resource_types end def newclass(name) @known_resource_types.add Puppet::Resource::Type.new(:hostclass, name) end def create_class_scope(name) klass = newclass(name) catalog = Puppet::Resource::Catalog.new catalog.add_resource(Puppet::Parser::Resource.new("stage", :main, :scope => Puppet::Parser::Scope.new)) Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source'), :catalog => catalog).evaluate @scope.class_scope(klass) end it "should be able to look up explicitly fully qualified variables from main" do other_scope = create_class_scope("") other_scope["othervar"] = "otherval" @scope["::othervar"].should == "otherval" end it "should be able to look up explicitly fully qualified variables from other scopes" do other_scope = create_class_scope("other") other_scope["var"] = "otherval" @scope["::other::var"].should == "otherval" end it "should be able to look up deeply qualified variables" do other_scope = create_class_scope("other::deep::klass") other_scope["var"] = "otherval" @scope["other::deep::klass::var"].should == "otherval" end it "should return nil for qualified variables that cannot be found in other classes" do other_scope = create_class_scope("other::deep::klass") @scope["other::deep::klass::var"].should be_nil end it "should warn and return nil for qualified variables whose classes have not been evaluated" do klass = newclass("other::deep::klass") @scope.expects(:warning) @scope["other::deep::klass::var"].should be_nil end it "should warn and return nil for qualified variables whose classes do not exist" do @scope.expects(:warning) @scope["other::deep::klass::var"].should be_nil end it "should return nil when asked for a non-string qualified variable from a class that does not exist" do @scope.stubs(:warning) @scope["other::deep::klass::var"].should be_nil end it "should return nil when asked for a non-string qualified variable from a class that has not been evaluated" do @scope.stubs(:warning) klass = newclass("other::deep::klass") @scope["other::deep::klass::var"].should be_nil end end end describe "when variables are set with append=true" do it "should raise an error if the variable is already defined in this scope" do @scope.setvar("var","1", :append => false) lambda { @scope.setvar("var","1", :append => true) }.should raise_error(Puppet::ParseError) end it "should lookup current variable value" do @scope.expects(:[]).with("var").returns("2") @scope.setvar("var","1", :append => true) end it "should store the concatenated string '42'" do @topscope.setvar("var","4", :append => false) @scope.setvar("var","2", :append => true) @scope["var"].should == "42" end it "should store the concatenated array [4,2]" do @topscope.setvar("var",[4], :append => false) @scope.setvar("var",[2], :append => true) @scope["var"].should == [4,2] end it "should store the merged hash {a => b, c => d}" do @topscope.setvar("var",{"a" => "b"}, :append => false) @scope.setvar("var",{"c" => "d"}, :append => true) @scope["var"].should == {"a" => "b", "c" => "d"} end it "should raise an error when appending a hash with something other than another hash" do @topscope.setvar("var",{"a" => "b"}, :append => false) lambda { @scope.setvar("var","not a hash", :append => true) }.should raise_error end end describe "when calling number?" do it "should return nil if called with anything not a number" do Puppet::Parser::Scope.number?([2]).should be_nil end it "should return a Fixnum for a Fixnum" do Puppet::Parser::Scope.number?(2).should be_an_instance_of(Fixnum) end it "should return a Float for a Float" do Puppet::Parser::Scope.number?(2.34).should be_an_instance_of(Float) end it "should return 234 for '234'" do Puppet::Parser::Scope.number?("234").should == 234 end it "should return nil for 'not a number'" do Puppet::Parser::Scope.number?("not a number").should be_nil end it "should return 23.4 for '23.4'" do Puppet::Parser::Scope.number?("23.4").should == 23.4 end it "should return 23.4e13 for '23.4e13'" do Puppet::Parser::Scope.number?("23.4e13").should == 23.4e13 end it "should understand negative numbers" do Puppet::Parser::Scope.number?("-234").should == -234 end it "should know how to convert exponential float numbers ala '23e13'" do Puppet::Parser::Scope.number?("23e13").should == 23e13 end it "should understand hexadecimal numbers" do Puppet::Parser::Scope.number?("0x234").should == 0x234 end it "should understand octal numbers" do Puppet::Parser::Scope.number?("0755").should == 0755 end it "should return nil on malformed integers" do Puppet::Parser::Scope.number?("0.24.5").should be_nil end it "should convert strings with leading 0 to integer if they are not octal" do Puppet::Parser::Scope.number?("0788").should == 788 end it "should convert strings of negative integers" do Puppet::Parser::Scope.number?("-0788").should == -788 end it "should return nil on malformed hexadecimal numbers" do Puppet::Parser::Scope.number?("0x89g").should be_nil end end describe "when using ephemeral variables" do it "should store the variable value" do @scope.setvar("1", :value, :ephemeral => true) @scope["1"].should == :value end it "should remove the variable value when unset_ephemeral_var is called" do @scope.setvar("1", :value, :ephemeral => true) @scope.stubs(:parent).returns(nil) @scope.unset_ephemeral_var @scope["1"].should be_nil end it "should not remove classic variables when unset_ephemeral_var is called" do @scope['myvar'] = :value1 @scope.setvar("1", :value2, :ephemeral => true) @scope.stubs(:parent).returns(nil) @scope.unset_ephemeral_var @scope["myvar"].should == :value1 end it "should raise an error when setting it again" do @scope.setvar("1", :value2, :ephemeral => true) lambda { @scope.setvar("1", :value3, :ephemeral => true) }.should raise_error end it "should declare ephemeral number only variable names" do @scope.ephemeral?("0").should be_true end it "should not declare ephemeral other variable names" do @scope.ephemeral?("abc0").should be_nil end describe "with more than one level" do it "should prefer latest ephemeral scopes" do @scope.setvar("0", :earliest, :ephemeral => true) @scope.new_ephemeral @scope.setvar("0", :latest, :ephemeral => true) @scope["0"].should == :latest end it "should be able to report the current level" do @scope.ephemeral_level.should == 1 @scope.new_ephemeral @scope.ephemeral_level.should == 2 end it "should check presence of an ephemeral variable accross multiple levels" do @scope.new_ephemeral @scope.setvar("1", :value1, :ephemeral => true) @scope.new_ephemeral @scope.setvar("0", :value2, :ephemeral => true) @scope.new_ephemeral @scope.ephemeral_include?("1").should be_true end it "should return false when an ephemeral variable doesn't exist in any ephemeral scope" do @scope.new_ephemeral @scope.setvar("1", :value1, :ephemeral => true) @scope.new_ephemeral @scope.setvar("0", :value2, :ephemeral => true) @scope.new_ephemeral @scope.ephemeral_include?("2").should be_false end it "should get ephemeral values from earlier scope when not in later" do @scope.setvar("1", :value1, :ephemeral => true) @scope.new_ephemeral @scope.setvar("0", :value2, :ephemeral => true) @scope["1"].should == :value1 end describe "when calling unset_ephemeral_var without a level" do it "should remove all the variables values" do @scope.setvar("1", :value1, :ephemeral => true) @scope.new_ephemeral @scope.setvar("1", :value2, :ephemeral => true) @scope.unset_ephemeral_var @scope["1"].should be_nil end end describe "when calling unset_ephemeral_var with a level" do it "should remove ephemeral scopes up to this level" do @scope.setvar("1", :value1, :ephemeral => true) @scope.new_ephemeral @scope.setvar("1", :value2, :ephemeral => true) @scope.new_ephemeral @scope.setvar("1", :value3, :ephemeral => true) @scope.unset_ephemeral_var(2) @scope["1"].should == :value2 end end end end describe "when setting ephemeral vars from matches" do before :each do @match = stub 'match', :is_a? => true @match.stubs(:[]).with(0).returns("this is a string") @match.stubs(:captures).returns([]) @scope.stubs(:setvar) end it "should accept only MatchData" do lambda { @scope.ephemeral_from("match") }.should raise_error end it "should set $0 with the full match" do @scope.expects(:setvar).with { |*arg| arg[0] == "0" and arg[1] == "this is a string" and arg[2][:ephemeral] } @scope.ephemeral_from(@match) end it "should set every capture as ephemeral var" do @match.stubs(:captures).returns([:capture1,:capture2]) @scope.expects(:setvar).with { |*arg| arg[0] == "1" and arg[1] == :capture1 and arg[2][:ephemeral] } @scope.expects(:setvar).with { |*arg| arg[0] == "2" and arg[1] == :capture2 and arg[2][:ephemeral] } @scope.ephemeral_from(@match) end it "should create a new ephemeral level" do @scope.expects(:new_ephemeral) @scope.ephemeral_from(@match) end end describe "when unsetting variables" do it "should be able to unset normal variables" do @scope["foo"] = "bar" @scope.unsetvar("foo") @scope["foo"].should be_nil end it "should be able to unset ephemeral variables" do @scope.setvar("0", "bar", :ephemeral => true) @scope.unsetvar("0") @scope["0"].should be_nil end it "should not unset ephemeral variables in previous ephemeral scope" do @scope.setvar("0", "bar", :ephemeral => true) @scope.new_ephemeral @scope.unsetvar("0") @scope["0"].should == "bar" end end it "should use its namespaces to find hostclasses" do klass = @scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "a::b::c") @scope.add_namespace "a::b" @scope.find_hostclass("c").should equal(klass) end it "should use its namespaces to find definitions" do define = @scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "a::b::c") @scope.add_namespace "a::b" @scope.find_definition("c").should equal(define) end describe "when managing defaults" do it "should be able to set and lookup defaults" do param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) @scope.define_settings(:mytype, param) @scope.lookupdefaults(:mytype).should == {:myparam => param} end it "should fail if a default is already defined and a new default is being defined" do param = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) @scope.define_settings(:mytype, param) lambda { @scope.define_settings(:mytype, param) }.should raise_error(Puppet::ParseError) end it "should return multiple defaults at once" do param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) @scope.define_settings(:mytype, param1) param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source")) @scope.define_settings(:mytype, param2) @scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2} end it "should look up defaults defined in parent scopes" do param1 = Puppet::Parser::Resource::Param.new(:name => :myparam, :value => "myvalue", :source => stub("source")) @scope.define_settings(:mytype, param1) child_scope = @scope.newscope param2 = Puppet::Parser::Resource::Param.new(:name => :other, :value => "myvalue", :source => stub("source")) child_scope.define_settings(:mytype, param2) child_scope.lookupdefaults(:mytype).should == {:myparam => param1, :other => param2} end end + + context "#true?" do + { "a string" => true, + "true" => true, + "false" => true, + true => true, + "" => false, + :undef => false + }.each do |input, output| + it "should treat #{input.inspect} as #{output}" do + Puppet::Parser::Scope.true?(input).should == output + end + end + end end diff --git a/spec/unit/provider/cron/crontab_spec.rb b/spec/unit/provider/cron/crontab_spec.rb new file mode 100755 index 000000000..e96e75bc1 --- /dev/null +++ b/spec/unit/provider/cron/crontab_spec.rb @@ -0,0 +1,116 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +describe Puppet::Type.type(:cron).provider(:crontab) do + subject do + provider = Puppet::Type.type(:cron).provider(:crontab) + provider.initvars + provider + end + + context "with the simple samples" do + FIELDS = { + :crontab => %w{command minute hour month monthday weekday}.collect { |o| o.intern }, + :freebsd_special => %w{special command}.collect { |o| o.intern }, + :environment => [:line], + :blank => [:line], + :comment => [:line], + } + + def compare_crontab_record(have, want) + want.each do |param, value| + have.should be_key param + have[param].should == value + end + + (FIELDS[have[:record_type]] - want.keys).each do |name| + have[name].should == :absent + end + end + + def compare_crontab_text(have, want) + # We should have four header lines, and then the text... + have.lines.to_a[0..3].should be_all {|x| x =~ /^# / } + have.lines.to_a[4..-1].join('').should == want + end + + ######################################################################## + # Simple input fixtures for testing. + samples = YAML.load(File.read(my_fixture('single_line.yaml'))) + + samples.each do |name, data| + it "should parse crontab line #{name} correctly" do + compare_crontab_record subject.parse_line(data[:text]), data[:record] + end + + it "should reconstruct the crontab line #{name} from the record" do + subject.to_line(data[:record]).should == data[:text] + end + end + + records = [] + text = "" + + # Sorting is from the original, and avoids :empty being the last line, + # since the provider will ignore that and cause this to fail. + samples.sort_by {|x| x.first.to_s }.each do |name, data| + records << data[:record] + text << data[:text] + "\n" + end + + it "should parse all sample records at once" do + subject.parse(text).zip(records).each do |round| + compare_crontab_record *round + end + end + + it "should reconstitute the file from the records" do + compare_crontab_text subject.to_file(records), text + end + + context "multi-line crontabs" do + tests = { :simple => [:spaces_in_command_with_times], + :with_name => [:name, :spaces_in_command_with_times], + :with_env => [:environment, :spaces_in_command_with_times], + :with_multiple_envs => [:environment, :lowercase_environment, :spaces_in_command_with_times], + :with_name_and_env => [:name_with_spaces, :another_env, :spaces_in_command_with_times], + :with_name_and_multiple_envs => [:long_name, :another_env, :fourth_env, :spaces_in_command_with_times] + } + + all_records = [] + all_text = '' + + tests.each do |name, content| + data = content.map {|x| samples[x] or raise "missing sample data #{x}" } + text = data.map {|x| x[:text] }.join("\n") + "\n" + records = data.map {|x| x[:record] } + + # Capture the whole thing for later, too... + all_records += records + all_text += text + + context name.to_s.gsub('_', ' ') do + it "should regenerate the text from the record" do + compare_crontab_text subject.to_file(records), text + end + + it "should parse the records from the text" do + subject.parse(text).zip(records).each do |round| + compare_crontab_record *round + end + end + end + end + + it "should parse the whole set of records from the text" do + subject.parse(all_text).zip(all_records).each do |round| + compare_crontab_record *round + end + end + + it "should regenerate the whole text from the set of all records" do + compare_crontab_text subject.to_file(all_records), all_text + end + end + end +end diff --git a/spec/unit/provider/mount/parsed_spec.rb b/spec/unit/provider/mount/parsed_spec.rb index 29c3cf020..8cb6efbc3 100755 --- a/spec/unit/provider/mount/parsed_spec.rb +++ b/spec/unit/provider/mount/parsed_spec.rb @@ -1,289 +1,289 @@ #!/usr/bin/env rspec require 'spec_helper' require 'shared_behaviours/all_parsedfile_providers' provider_class = Puppet::Type.type(:mount).provider(:parsed) describe provider_class, :unless => Puppet.features.microsoft_windows? do before :each do @mount_class = Puppet::Type.type(:mount) @provider = @mount_class.provider(:parsed) end # LAK:FIXME I can't mock Facter because this test happens at parse-time. it "should default to /etc/vfstab on Solaris" do pending "This test only works on Solaris" unless Facter.value(:operatingsystem) == 'Solaris' Puppet::Type.type(:mount).provider(:parsed).default_target.should == '/etc/vfstab' end it "should default to /etc/fstab on anything else" do pending "This test does not work on Solaris" if Facter.value(:operatingsystem) == 'Solaris' Puppet::Type.type(:mount).provider(:parsed).default_target.should == '/etc/fstab' end describe "when parsing a line" do it "should not crash on incomplete lines in fstab" do parse = @provider.parse <<-FSTAB /dev/incomplete /dev/device name FSTAB lambda{ @provider.to_line(parse[0]) }.should_not raise_error end # it_should_behave_like "all parsedfile providers", # provider_class, my_fixtures('*.fstab') - describe "on Solaris", :if => Facter.value(:operatingsystem) == 'Solaris', :'fails_on_ruby_1.9.2' => true do + describe "on Solaris", :if => Facter.value(:operatingsystem) == 'Solaris' do before :each do @example_line = "/dev/dsk/c0d0s0 /dev/rdsk/c0d0s0 \t\t / \t ufs 1 no\t-" end it "should extract device from the first field" do @provider.parse_line(@example_line)[:device].should == '/dev/dsk/c0d0s0' end it "should extract blockdevice from second field" do @provider.parse_line(@example_line)[:blockdevice].should == "/dev/rdsk/c0d0s0" end it "should extract name from third field" do @provider.parse_line(@example_line)[:name].should == "/" end it "should extract fstype from fourth field" do @provider.parse_line(@example_line)[:fstype].should == "ufs" end it "should extract pass from fifth field" do @provider.parse_line(@example_line)[:pass].should == "1" end it "should extract atboot from sixth field" do @provider.parse_line(@example_line)[:atboot].should == "no" end it "should extract options from seventh field" do @provider.parse_line(@example_line)[:options].should == "-" end end describe "on other platforms than Solaris", :if => Facter.value(:operatingsystem) != 'Solaris' do before :each do @example_line = "/dev/vg00/lv01\t/spare \t \t ext3 defaults\t1 2" end it "should extract device from the first field" do @provider.parse_line(@example_line)[:device].should == '/dev/vg00/lv01' end it "should extract name from second field" do @provider.parse_line(@example_line)[:name].should == "/spare" end it "should extract fstype from third field" do @provider.parse_line(@example_line)[:fstype].should == "ext3" end it "should extract options from fourth field" do @provider.parse_line(@example_line)[:options].should == "defaults" end it "should extract dump from fifth field" do @provider.parse_line(@example_line)[:dump].should == "1" end it "should extract options from sixth field" do @provider.parse_line(@example_line)[:pass].should == "2" end end end describe "mountinstances" do it "should get name from mountoutput found on Solaris" do Facter.stubs(:value).with(:operatingsystem).returns 'Solaris' @provider.stubs(:mountcmd).returns(File.read(my_fixture('solaris.mount'))) mounts = @provider.mountinstances mounts.size.should == 6 mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/proc', :mounted => :yes } mounts[2].should == { :name => '/etc/mnttab', :mounted => :yes } mounts[3].should == { :name => '/tmp', :mounted => :yes } mounts[4].should == { :name => '/export/home', :mounted => :yes } mounts[5].should == { :name => '/ghost', :mounted => :yes } end it "should get name from mountoutput found on HP-UX" do Facter.stubs(:value).with(:operatingsystem).returns 'HP-UX' @provider.stubs(:mountcmd).returns(File.read(my_fixture('hpux.mount'))) mounts = @provider.mountinstances mounts.size.should == 17 mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/devices', :mounted => :yes } mounts[2].should == { :name => '/dev', :mounted => :yes } mounts[3].should == { :name => '/system/contract', :mounted => :yes } mounts[4].should == { :name => '/proc', :mounted => :yes } mounts[5].should == { :name => '/etc/mnttab', :mounted => :yes } mounts[6].should == { :name => '/etc/svc/volatile', :mounted => :yes } mounts[7].should == { :name => '/system/object', :mounted => :yes } mounts[8].should == { :name => '/etc/dfs/sharetab', :mounted => :yes } mounts[9].should == { :name => '/lib/libc.so.1', :mounted => :yes } mounts[10].should == { :name => '/dev/fd', :mounted => :yes } mounts[11].should == { :name => '/tmp', :mounted => :yes } mounts[12].should == { :name => '/var/run', :mounted => :yes } mounts[13].should == { :name => '/export', :mounted => :yes } mounts[14].should == { :name => '/export/home', :mounted => :yes } mounts[15].should == { :name => '/rpool', :mounted => :yes } mounts[16].should == { :name => '/ghost', :mounted => :yes } end it "should get name from mountoutput found on Darwin" do Facter.stubs(:value).with(:operatingsystem).returns 'Darwin' @provider.stubs(:mountcmd).returns(File.read(my_fixture('darwin.mount'))) mounts = @provider.mountinstances mounts.size.should == 6 mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/dev', :mounted => :yes } mounts[2].should == { :name => '/net', :mounted => :yes } mounts[3].should == { :name => '/home', :mounted => :yes } mounts[4].should == { :name => '/usr', :mounted => :yes } mounts[5].should == { :name => '/ghost', :mounted => :yes } end it "should get name from mountoutput found on Linux" do Facter.stubs(:value).with(:operatingsystem).returns 'Gentoo' @provider.stubs(:mountcmd).returns(File.read(my_fixture('linux.mount'))) mounts = @provider.mountinstances mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/lib64/rc/init.d', :mounted => :yes } mounts[2].should == { :name => '/sys', :mounted => :yes } mounts[3].should == { :name => '/usr/portage', :mounted => :yes } mounts[4].should == { :name => '/ghost', :mounted => :yes } end it "should get name from mountoutput found on AIX" do Facter.stubs(:value).with(:operatingsystem).returns 'AIX' @provider.stubs(:mountcmd).returns(File.read(my_fixture('aix.mount'))) mounts = @provider.mountinstances mounts[0].should == { :name => '/', :mounted => :yes } mounts[1].should == { :name => '/tmp', :mounted => :yes } mounts[2].should == { :name => '/home', :mounted => :yes } mounts[3].should == { :name => '/usr', :mounted => :yes } mounts[4].should == { :name => '/usr/code', :mounted => :yes } end it "should raise an error if a line is not understandable" do @provider.stubs(:mountcmd).returns("bazinga!") lambda { @provider.mountinstances }.should raise_error Puppet::Error end end it "should support AIX's paragraph based /etc/filesystems" my_fixtures('*.fstab').each do |fstab| platform = File.basename(fstab, '.fstab') describe "when calling instances on #{platform}" do before :each do if Facter[:operatingsystem] == "Solaris" then platform == 'solaris' or pending "We need to stub the operatingsystem fact at load time, but can't" else platform != 'solaris' or pending "We need to stub the operatingsystem fact at load time, but can't" end # Stub the mount output to our fixture. begin mount = my_fixture(platform + '.mount') @provider.stubs(:mountcmd).returns File.read(mount) rescue pending "is #{platform}.mount missing at this point?" end # Note: we have to stub default_target before creating resources # because it is used by Puppet::Type::Mount.new to populate the # :target property. @provider.stubs(:default_target).returns fstab @retrieve = @provider.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}} end # Following mountpoint are present in all fstabs/mountoutputs it "should include unmounted resources" do @retrieve.should include(:name => '/', :ensure => :mounted) end it "should include mounted resources" do @retrieve.should include(:name => '/boot', :ensure => :unmounted) end it "should include ghost resources" do @retrieve.should include(:name => '/ghost', :ensure => :ghost) end end describe "when prefetching on #{platform}" do before :each do if Facter[:operatingsystem] == "Solaris" then platform == 'solaris' or pending "We need to stub the operatingsystem fact at load time, but can't" else platform != 'solaris' or pending "We need to stub the operatingsystem fact at load time, but can't" end # Stub the mount output to our fixture. begin mount = my_fixture(platform + '.mount') @provider.stubs(:mountcmd).returns File.read(mount) rescue pending "is #{platform}.mount missing at this point?" end # Note: we have to stub default_target before creating resources # because it is used by Puppet::Type::Mount.new to populate the # :target property. @provider.stubs(:default_target).returns fstab @res_ghost = Puppet::Type::Mount.new(:name => '/ghost') # in no fake fstab @res_mounted = Puppet::Type::Mount.new(:name => '/') # in every fake fstab @res_unmounted = Puppet::Type::Mount.new(:name => '/boot') # in every fake fstab @res_absent = Puppet::Type::Mount.new(:name => '/absent') # in no fake fstab # Simulate transaction.rb:prefetch @resource_hash = {} [@res_ghost, @res_mounted, @res_unmounted, @res_absent].each do |resource| @resource_hash[resource.name] = resource end end it "should set :ensure to :unmounted if found in fstab but not mounted" do @provider.prefetch(@resource_hash) @res_unmounted.provider.get(:ensure).should == :unmounted end it "should set :ensure to :ghost if not found in fstab but mounted" do @provider.prefetch(@resource_hash) @res_ghost.provider.get(:ensure).should == :ghost end it "should set :ensure to :mounted if found in fstab and mounted" do @provider.prefetch(@resource_hash) @res_mounted.provider.get(:ensure).should == :mounted end it "should set :ensure to :absent if not found in fstab and not mounted" do @provider.prefetch(@resource_hash) @res_absent.provider.get(:ensure).should == :absent end end end end diff --git a/spec/unit/provider/package/aptitude_spec.rb b/spec/unit/provider/package/aptitude_spec.rb new file mode 100755 index 000000000..fc531a1f8 --- /dev/null +++ b/spec/unit/provider/package/aptitude_spec.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +describe Puppet::Type.type(:package).provider(:aptitude) do + let :type do Puppet::Type.type(:package) end + let :pkg do + type.new(:name => 'faff', :provider => :aptitude, :source => '/tmp/faff.deb') + end + + it { should be_versionable } + + context "when retrieving ensure" do + { :absent => "deinstall ok config-files faff 1.2.3-1\n", + "1.2.3-1" => "install ok installed faff 1.2.3-1\n", + }.each do |expect, output| + it "should detect #{expect} packages" do + pkg.provider.expects(:dpkgquery). + with('-W', '--showformat', '${Status} ${Package} ${Version}\n', 'faff'). + returns(output) + + pkg.property(:ensure).retrieve.should == expect + end + end + end + + it "should try and install when asked" do + pkg.provider.expects(:aptitude). + with('-y', '-o', 'DPkg::Options::=--force-confold', :install, 'faff'). + returns(0) + + pkg.provider.install + end + + it "should try and purge when asked" do + pkg.provider.expects(:aptitude).with('-y', 'purge', 'faff').returns(0) + pkg.provider.purge + end +end diff --git a/spec/unit/provider/package/aptrpm_spec.rb b/spec/unit/provider/package/aptrpm_spec.rb new file mode 100755 index 000000000..d12dfd3f6 --- /dev/null +++ b/spec/unit/provider/package/aptrpm_spec.rb @@ -0,0 +1,39 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +describe Puppet::Type.type(:package).provider(:aptrpm) do + let :type do Puppet::Type.type(:package) end + let :pkg do + type.new(:name => 'faff', :provider => :aptrpm, :source => '/tmp/faff.rpm') + end + + it { should be_versionable } + + context "when retrieving ensure" do + def rpm + pkg.provider.expects(:rpm). + with('-q', 'faff', '--nosignature', '--nodigest', '--qf', + "%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH}\n") + end + + it "should report absent packages" do + rpm.raises(Puppet::ExecutionFailure, "couldn't find rpm") + pkg.property(:ensure).retrieve.should == :absent + end + + it "should report present packages correctly" do + rpm.returns("faff-1.2.3-1 0 1.2.3-1 5 i686\n") + pkg.property(:ensure).retrieve.should == "1.2.3-1-5" + end + end + + it "should try and install when asked" do + pkg.provider.expects(:aptget). with('-q', '-y', 'install', 'faff'). returns(0) + pkg.provider.install + end + + it "should try and purge when asked" do + pkg.provider.expects(:aptget).with('-y', '-q', 'remove', '--purge', 'faff').returns(0) + pkg.provider.purge + end +end diff --git a/spec/unit/provider/package/pkg_spec.rb b/spec/unit/provider/package/pkg_spec.rb index 50a87cea3..fe0977702 100755 --- a/spec/unit/provider/package/pkg_spec.rb +++ b/spec/unit/provider/package/pkg_spec.rb @@ -1,85 +1,85 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Type.type(:package).provider(:pkg) do before :each do @resource = Puppet::Resource.new(:package, 'dummy', :parameters => {:name => 'dummy', :ensure => :latest}) @provider = described_class.new(@resource) end def self.it_should_respond_to(*actions) actions.each do |action| it "should respond to :#{action}" do @provider.should respond_to(action) end end end it_should_respond_to :install, :uninstall, :update, :query, :latest it "should not be versionable" do described_class.should_not be_versionable end it "should use :install to update" do @provider.expects(:install) @provider.update end describe "when calling instances" do it "should correctly parse lines with preferred publisher" do described_class.expects(:pkg).with(:list,'-H').returns File.read(my_fixture('simple')) @instances = described_class.instances.map { |p| Hash.new(:name => p.get(:name), :ensure => p.get(:ensure)) } @instances.size.should == 4 @instances[0].should == Hash.new(:name => 'SUNPython', :ensure => :present) @instances[1].should == Hash.new(:name => 'SUNWbind', :ensure => :present) @instances[2].should == Hash.new(:name => 'SUNWdistro-license-copyright', :ensure => :present) @instances[3].should == Hash.new(:name => 'SUNWfppd', :ensure => :present) end it "should correctly parse lines with non preferred publisher" do described_class.expects(:pkg).with(:list,'-H').returns File.read(my_fixture('publisher')) @instances = described_class.instances.map { |p| Hash.new(:name => p.get(:name), :ensure => p.get(:ensure)) } @instances.size.should == 2 @instances[0].should == Hash.new(:name => 'SUNWpcre', :ensure => :present) @instances[1].should == Hash.new(:name => 'service/network/ssh', :ensure => :present) end it "should warn about incorrect lines" do fake_output = File.read(my_fixture('incomplete')) - error_line = fake_output.lines[0] + error_line = fake_output.split($/).first described_class.expects(:pkg).with(:list,'-H').returns fake_output described_class.expects(:warning).with "Failed to match 'pkg list' line #{error_line.inspect}" described_class.instances end end describe "when query a package" do it "should find the package" do @provider.stubs(:pkg).with(:list,'-H','dummy').returns File.read(my_fixture('dummy')) @provider.query.should == { :name => 'dummy', :ensure => :present, :version => '2.5.5-0.111', :status => "installed", :provider => :pkg, } end it "should return :absent when the package is not found" do # I dont know what the acutal error looks like, but according to type/pkg.rb we're just # reacting on the Exception anyways @provider.expects(:pkg).with(:list, "-H", "dummy").raises Puppet::ExecutionFailure, 'Not found' @provider.query.should == {:ensure => :absent, :name => "dummy"} end it "should return :absent when the packageline cannot be parsed" do @provider.stubs(:pkg).with(:list,'-H','dummy').returns File.read(my_fixture('incomplete')) @provider.query.should == { :name => 'dummy', :ensure => :absent } end end end diff --git a/spec/unit/provider/service/base_spec.rb b/spec/unit/provider/service/base_spec.rb new file mode 100755 index 000000000..9522fd7f8 --- /dev/null +++ b/spec/unit/provider/service/base_spec.rb @@ -0,0 +1,77 @@ +#!/usr/bin/env rspec +require 'spec_helper' +require 'rbconfig' +require 'fileutils' + +provider_class = Puppet::Type.type(:service).provider(:init) + +describe "base service provider" do + include PuppetSpec::Files + + let :type do Puppet::Type.type(:service) end + let :provider do type.provider(:base) end + + subject { provider } + + context "basic operations" do + # Cross-platform file interactions. Fun times. + Ruby = File.join(RbConfig::CONFIG["bindir"], + RbConfig::CONFIG["RUBY_INSTALL_NAME"] + + RbConfig::CONFIG["EXEEXT"]) + + Start = "#{Ruby} -rfileutils -e 'FileUtils.touch(ARGV[0])'" + Status = "#{Ruby} -e 'exit File.file?(ARGV[0])'" + Stop = "#{Ruby} -e 'File.exist?(ARGV[0]) and File.unlink(ARGV[0])'" + + let :flag do tmpfile('base-service-test') end + + subject do + type.new(:name => "test", :provider => :base, + :start => "#{Start} #{flag}", + :status => "#{Status} #{flag}", + :stop => "#{Stop} #{flag}" + ).provider + end + + before :each do + File.unlink(flag) if File.exist?(flag) + end + + it { should be } + + it "should invoke the start command if not running" do + File.should_not be_file flag + subject.start + File.should be_file flag + end + + it "should be stopped before being started" do + subject.status.should == :stopped + end + + it "should be running after being started" do + subject.start + subject.status.should == :running + end + + it "should invoke the stop command when asked" do + subject.start + subject.status.should == :running + subject.stop + subject.status.should == :stopped + File.should_not be_file flag + end + + it "should start again even if already running" do + subject.start + subject.expects(:ucommand).with(:start) + subject.start + end + + it "should stop again even if already stopped" do + subject.stop + subject.expects(:ucommand).with(:stop) + subject.stop + end + end +end diff --git a/spec/unit/provider/service/init_spec.rb b/spec/unit/provider/service/init_spec.rb index 8374594e7..2b900ef8a 100755 --- a/spec/unit/provider/service/init_spec.rb +++ b/spec/unit/provider/service/init_spec.rb @@ -1,170 +1,170 @@ #!/usr/bin/env rspec # # Unit testing for the Init service Provider # require 'spec_helper' provider_class = Puppet::Type.type(:service).provider(:init) describe provider_class do before :each do @class = Puppet::Type.type(:service).provider(:init) @resource = stub 'resource' @resource.stubs(:[]).returns(nil) @resource.stubs(:[]).with(:name).returns "myservice" # @resource.stubs(:[]).with(:ensure).returns :enabled @resource.stubs(:[]).with(:path).returns ["/service/path","/alt/service/path"] # @resource.stubs(:ref).returns "Service[myservice]" File.stubs(:directory?).returns(true) @provider = provider_class.new @provider.resource = @resource end describe "when getting all service instances" do before :each do @services = ['one', 'two', 'three', 'four'] Dir.stubs(:entries).returns @services FileTest.stubs(:directory?).returns(true) FileTest.stubs(:executable?).returns(true) @class.stubs(:defpath).returns('tmp') end it "should return instances for all services" do @services.each do |inst| @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance") end results = @services.collect {|x| "#{x}_instance"} @class.instances.should == results end it "should omit an array of services from exclude list" do exclude = ['two', 'four'] (@services-exclude).each do |inst| @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance") end results = (@services-exclude).collect {|x| "#{x}_instance"} @class.get_services(@class.defpath, exclude).should == results end - it "should omit a single service from the exclude list", :'fails_on_ruby_1.9.2' => true do + it "should omit a single service from the exclude list" do exclude = 'two' - (@services-exclude.to_a).each do |inst| + (@services - [exclude]).each do |inst| @class.expects(:new).with{|hash| hash[:name] == inst}.returns("#{inst}_instance") end results = @services.reject{|x| x==exclude }.collect {|x| "#{x}_instance"} @class.get_services(@class.defpath, exclude).should == results end it "should use defpath" do @services.each do |inst| @class.expects(:new).with{|hash| hash[:path] == @class.defpath}.returns("#{inst}_instance") end results = @services.sort.collect {|x| "#{x}_instance"} @class.instances.sort.should == results end it "should set hasstatus to true for providers" do @services.each do |inst| @class.expects(:new).with{|hash| hash[:name] == inst && hash[:hasstatus] == true}.returns("#{inst}_instance") end results = @services.collect {|x| "#{x}_instance"} @class.instances.should == results end end describe "when searching for the init script" do it "should discard paths that do not exist" do File.stubs(:exist?).returns(false) File.stubs(:directory?).returns(false) @provider.paths.should be_empty end it "should discard paths that are not directories" do File.stubs(:exist?).returns(true) File.stubs(:directory?).returns(false) @provider.paths.should be_empty end it "should be able to find the init script in the service path" do File.stubs(:stat).raises(Errno::ENOENT.new('No such file or directory')) File.expects(:stat).with("/service/path/myservice").returns true @provider.initscript.should == "/service/path/myservice" end it "should be able to find the init script in the service path" do File.stubs(:stat).raises(Errno::ENOENT.new('No such file or directory')) File.expects(:stat).with("/alt/service/path/myservice").returns true @provider.initscript.should == "/alt/service/path/myservice" end it "should fail if the service isn't there" do lambda { @provider.initscript }.should raise_error(Puppet::Error, "Could not find init script for 'myservice'") end end describe "if the init script is present" do before :each do File.stubs(:stat).with("/service/path/myservice").returns true end [:start, :stop, :status, :restart].each do |method| it "should have a #{method} method" do @provider.should respond_to(method) end describe "when running #{method}" do it "should use any provided explicit command" do @resource.stubs(:[]).with(method).returns "/user/specified/command" @provider.expects(:execute).with { |command, *args| command == ["/user/specified/command"] } @provider.send(method) end it "should pass #{method} to the init script when no explicit command is provided" do @resource.stubs(:[]).with("has#{method}".intern).returns :true @provider.expects(:execute).with { |command, *args| command == ["/service/path/myservice",method]} @provider.send(method) end end end describe "when checking status" do describe "when hasstatus is :true" do before :each do @resource.stubs(:[]).with(:hasstatus).returns :true end it "should execute the command" do @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("") @provider.status end it "should consider the process running if the command returns 0" do @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("") $CHILD_STATUS.stubs(:exitstatus).returns(0) @provider.status.should == :running end [-10,-1,1,10].each { |ec| it "should consider the process stopped if the command returns something non-0" do @provider.expects(:texecute).with(:status, ['/service/path/myservice', :status], false).returns("") $CHILD_STATUS.stubs(:exitstatus).returns(ec) @provider.status.should == :stopped end } end describe "when hasstatus is not :true" do it "should consider the service :running if it has a pid" do @provider.expects(:getpid).returns "1234" @provider.status.should == :running end it "should consider the service :stopped if it doesn't have a pid" do @provider.expects(:getpid).returns nil @provider.status.should == :stopped end end end describe "when restarting and hasrestart is not :true" do it "should stop and restart the process" do @provider.expects(:texecute).with(:stop, ['/service/path/myservice', :stop ], true).returns("") @provider.expects(:texecute).with(:start,['/service/path/myservice', :start], true).returns("") $CHILD_STATUS.stubs(:exitstatus).returns(0) @provider.restart end end end end diff --git a/spec/unit/provider/service/src_spec.rb b/spec/unit/provider/service/src_spec.rb index b45ca0c7c..17f49994e 100755 --- a/spec/unit/provider/service/src_spec.rb +++ b/spec/unit/provider/service/src_spec.rb @@ -1,97 +1,97 @@ #!/usr/bin/env rspec # # Unit testing for the AIX System Resource Controller (src) provider # require 'spec_helper' provider_class = Puppet::Type.type(:service).provider(:src) describe provider_class do before :each do @resource = stub 'resource' @resource.stubs(:[]).returns(nil) @resource.stubs(:[]).with(:name).returns "myservice" @provider = provider_class.new @provider.resource = @resource @provider.stubs(:command).with(:stopsrc).returns "/usr/bin/stopsrc" @provider.stubs(:command).with(:startsrc).returns "/usr/bin/startsrc" @provider.stubs(:command).with(:lssrc).returns "/usr/bin/lssrc" @provider.stubs(:command).with(:refresh).returns "/usr/bin/refresh" @provider.stubs(:stopsrc) @provider.stubs(:startsrc) @provider.stubs(:lssrc) @provider.stubs(:refresh) end [:start, :stop, :status, :restart].each do |method| it "should have a #{method} method" do @provider.should respond_to(method) end end it "should execute the startsrc command" do @provider.expects(:execute).with(['/usr/bin/startsrc', '-s', "myservice"], {:squelch => true, :failonfail => true}) @provider.start end it "should execute the stopsrc command" do @provider.expects(:execute).with(['/usr/bin/stopsrc', '-s', "myservice"], {:squelch => true, :failonfail => true}) @provider.stop end - it "should execute status and return running if the subsystem is active", :'fails_on_ruby_1.9.2' => true do + it "should execute status and return running if the subsystem is active" do sample_output = <<_EOF_ Subsystem Group PID Status myservice tcpip 1234 active _EOF_ @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output @provider.status.should == :running end - it "should execute status and return stopped if the subsystem is inoperative", :'fails_on_ruby_1.9.2' => true do + it "should execute status and return stopped if the subsystem is inoperative" do sample_output = <<_EOF_ Subsystem Group PID Status myservice tcpip inoperative _EOF_ @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output @provider.status.should == :stopped end - it "should execute status and return nil if the status is not known", :'fails_on_ruby_1.9.2' => true do + it "should execute status and return nil if the status is not known" do sample_output = <<_EOF_ Subsystem Group PID Status myservice tcpip randomdata _EOF_ @provider.expects(:execute).with(['/usr/bin/lssrc', '-s', "myservice"]).returns sample_output @provider.status.should == nil end - it "should execute restart which runs refresh", :'fails_on_ruby_1.9.2' => true do + it "should execute restart which runs refresh" do sample_output = <<_EOF_ #subsysname:synonym:cmdargs:path:uid:auditid:standin:standout:standerr:action:multi:contact:svrkey:svrmtype:priority:signorm:sigforce:display:waittime:grpname: myservice:::/usr/sbin/inetd:0:0:/dev/console:/dev/console:/dev/console:-O:-Q:-K:0:0:20:0:0:-d:20:tcpip: _EOF_ @provider.expects(:execute).with(['/usr/bin/lssrc', '-Ss', "myservice"]).returns sample_output @provider.expects(:execute).with(['/usr/bin/refresh', '-s', "myservice"]) @provider.restart end - it "should execute restart which runs stopsrc then startsrc", :'fails_on_ruby_1.9.2' => true do + it "should execute restart which runs stopsrc then startsrc" do sample_output = <<_EOF_ #subsysname:synonym:cmdargs:path:uid:auditid:standin:standout:standerr:action:multi:contact:svrkey:svrmtype:priority:signorm:sigforce:display:waittime:grpname: myservice::--no-daemonize:/usr/sbin/puppetd:0:0:/dev/null:/var/log/puppet.log:/var/log/puppet.log:-O:-Q:-S:0:0:20:15:9:-d:20::" _EOF_ @provider.expects(:execute).with(['/usr/bin/lssrc', '-Ss', "myservice"]).returns sample_output @provider.expects(:execute).with(['/usr/bin/stopsrc', '-s', "myservice"], {:squelch => true, :failonfail => true}) @provider.expects(:execute).with(['/usr/bin/startsrc', '-s', "myservice"], {:squelch => true, :failonfail => true}) @provider.restart end end diff --git a/spec/unit/provider/sshkey/parsed_spec.rb b/spec/unit/provider/sshkey/parsed_spec.rb index e66032bc4..1cf91c50d 100755 --- a/spec/unit/provider/sshkey/parsed_spec.rb +++ b/spec/unit/provider/sshkey/parsed_spec.rb @@ -1,37 +1,67 @@ #!/usr/bin/env rspec require 'spec_helper' provider_class = Puppet::Type.type(:sshkey).provider(:parsed) -describe provider_class do - before do - @sshkey_class = Puppet::Type.type(:sshkey) - @provider_class = @sshkey_class.provider(:parsed) - @key = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzwHhxXvIrtfIwrudFqc8yQcIfMudrgpnuh1F3AV6d2BrLgu/yQE7W5UyJMUjfj427sQudRwKW45O0Jsnr33F4mUw+GIMlAAmp9g24/OcrTiB8ZUKIjoPy/cO4coxGi8/NECtRzpD/ZUPFh6OEpyOwJPMb7/EC2Az6Otw4StHdXUYw22zHazBcPFnv6zCgPx1hA7QlQDWTu4YcL0WmTYQCtMUb3FUqrcFtzGDD0ytosgwSd+JyN5vj5UwIABjnNOHPZ62EY1OFixnfqX/+dUwrFSs5tPgBF/KkC6R7tmbUfnBON6RrGEmu+ajOTOLy23qUZB4CQ53V7nyAWhzqSK+hw==' +describe "sshkey parsed provider" do + let :type do Puppet::Type.type(:sshkey) end + let :provider do type.provider(:parsed) end + subject { provider } + + def key + 'AAAAB3NzaC1yc2EAAAABIwAAAQEAzwHhxXvIrtfIwrudFqc8yQcIfMudrgpnuh1F3AV6d2BrLgu/yQE7W5UyJMUjfj427sQudRwKW45O0Jsnr33F4mUw+GIMlAAmp9g24/OcrTiB8ZUKIjoPy/cO4coxGi8/NECtRzpD/ZUPFh6OEpyOwJPMb7/EC2Az6Otw4StHdXUYw22zHazBcPFnv6zCgPx1hA7QlQDWTu4YcL0WmTYQCtMUb3FUqrcFtzGDD0ytosgwSd+JyN5vj5UwIABjnNOHPZ62EY1OFixnfqX/+dUwrFSs5tPgBF/KkC6R7tmbUfnBON6RrGEmu+ajOTOLy23qUZB4CQ53V7nyAWhzqSK+hw==' end it "should parse the name from the first field" do - @provider_class.parse_line('test ssh-rsa '+@key)[:name].should == "test" + subject.parse_line('test ssh-rsa '+key)[:name].should == "test" end it "should parse the first component of the first field as the name" do - @provider_class.parse_line('test,alias ssh-rsa '+@key)[:name].should == "test" + subject.parse_line('test,alias ssh-rsa '+key)[:name].should == "test" end it "should parse host_aliases from the remaining components of the first field" do - @provider_class.parse_line('test,alias ssh-rsa '+@key)[:host_aliases].should == ["alias"] + subject.parse_line('test,alias ssh-rsa '+key)[:host_aliases].should == ["alias"] end it "should parse multiple host_aliases" do - @provider_class.parse_line('test,alias1,alias2,alias3 ssh-rsa '+@key)[:host_aliases].should == ["alias1","alias2","alias3"] + subject.parse_line('test,alias1,alias2,alias3 ssh-rsa '+key)[:host_aliases].should == ["alias1","alias2","alias3"] end it "should not drop an empty host_alias" do - @provider_class.parse_line('test,alias, ssh-rsa '+@key)[:host_aliases].should == ["alias",""] + subject.parse_line('test,alias, ssh-rsa '+key)[:host_aliases].should == ["alias",""] end it "should recognise when there are no host aliases" do - @provider_class.parse_line('test ssh-rsa '+@key)[:host_aliases].should == [] + subject.parse_line('test ssh-rsa '+key)[:host_aliases].should == [] end + context "with the sample file" do + let :fixture do my_fixture('sample') end + before :each do subject.stubs(:default_target).returns(fixture) end + + it "should parse to records on prefetch" do + subject.target_records(fixture).should be_empty + subject.prefetch + + records = subject.target_records(fixture) + records.should be_an Array + records.should be_all {|x| x.should be_an Hash } + end + + it "should reconstitute the file from records" do + subject.prefetch + records = subject.target_records(fixture) + + text = subject.to_file(records).gsub(/^# HEADER.+\n/, '') + + oldlines = File.readlines(fixture).map(&:chomp) + newlines = text.chomp.split("\n") + oldlines.length.should == newlines.length + + oldlines.zip(newlines).each do |old, new| + old.gsub(/\s+/, '').should == new.gsub(/\s+/, '') + end + end + end end diff --git a/spec/unit/provider/user/user_role_add_spec.rb b/spec/unit/provider/user/user_role_add_spec.rb index d6235cb4b..6d779642b 100755 --- a/spec/unit/provider/user/user_role_add_spec.rb +++ b/spec/unit/provider/user/user_role_add_spec.rb @@ -1,303 +1,306 @@ require 'spec_helper' require 'puppet_spec/files' require 'tempfile' provider_class = Puppet::Type.type(:user).provider(:user_role_add) describe provider_class, :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files before do @resource = stub("resource", :name => "myuser", :managehome? => nil) + @resource.stubs(:should).returns "fakeval" + @resource.stubs(:should).with(:keys).returns Hash.new @resource.stubs(:[]).returns "fakeval" + @resource.stubs(:allowdupe?).returns false @provider = provider_class.new(@resource) end describe "when calling command" do before do klass = stub("provider") klass.stubs(:command).with(:foo).returns("userfoo") klass.stubs(:command).with(:role_foo).returns("rolefoo") @provider.stubs(:class).returns(klass) end it "should use the command if not a role and ensure!=role" do @provider.stubs(:is_role?).returns(false) @provider.stubs(:exists?).returns(false) @resource.stubs(:[]).with(:ensure).returns(:present) @provider.command(:foo).should == "userfoo" end it "should use the role command when a role" do @provider.stubs(:is_role?).returns(true) @provider.command(:foo).should == "rolefoo" end it "should use the role command when !exists and ensure=role" do @provider.stubs(:is_role?).returns(false) @provider.stubs(:exists?).returns(false) @resource.stubs(:[]).with(:ensure).returns(:role) @provider.command(:foo).should == "rolefoo" end end - describe "when calling transition", :'fails_on_ruby_1.9.2' => true do + describe "when calling transition" do it "should return the type set to whatever is passed in" do @provider.expects(:command).with(:modify).returns("foomod") @provider.transition("bar").include?("type=bar") end end describe "when calling create" do before do @provider.stubs(:password=) end it "should use the add command when the user is not a role" do @provider.stubs(:is_role?).returns(false) @provider.expects(:addcmd).returns("useradd") @provider.expects(:run).at_least_once @provider.create end it "should use transition(normal) when the user is a role" do @provider.stubs(:is_role?).returns(true) @provider.expects(:transition).with("normal") @provider.expects(:run) @provider.create end it "should set password age rules" do @resource = Puppet::Type.type(:user).new :name => "myuser", :password_min_age => 5, :password_max_age => 10, :provider => :user_role_add @provider = provider_class.new(@resource) @provider.stubs(:user_attributes) @provider.stubs(:execute) @provider.expects(:execute).with { |cmd, *args| args == ["-n", 5, "-x", 10, "myuser"] } @provider.create end end describe "when calling destroy" do it "should use the delete command if the user exists and is not a role" do @provider.stubs(:exists?).returns(true) @provider.stubs(:is_role?).returns(false) @provider.expects(:deletecmd) @provider.expects(:run) @provider.destroy end it "should use the delete command if the user is a role" do @provider.stubs(:exists?).returns(true) @provider.stubs(:is_role?).returns(true) @provider.expects(:deletecmd) @provider.expects(:run) @provider.destroy end end describe "when calling create_role" do it "should use the transition(role) if the user exists" do @provider.stubs(:exists?).returns(true) @provider.stubs(:is_role?).returns(false) @provider.expects(:transition).with("role") @provider.expects(:run) @provider.create_role end it "should use the add command when role doesn't exists" do @provider.stubs(:exists?).returns(false) @provider.expects(:addcmd) @provider.expects(:run) @provider.create_role end end describe "when allow duplicate is enabled" do before do @resource.expects(:allowdupe?).returns true @resource.stubs(:system?) @provider.stubs(:is_role?).returns(false) @provider.stubs(:execute) @provider.expects(:execute).with { |args| args.include?("-o") } end - it "should add -o when the user is being created", :'fails_on_ruby_1.9.2' => true do + it "should add -o when the user is being created" do @provider.stubs(:password=) @provider.create end it "should add -o when the uid is being modified" do @provider.uid = 150 end end [:roles, :auths, :profiles].each do |val| describe "when getting #{val}" do it "should get the user_attributes" do @provider.expects(:user_attributes) @provider.send(val) end it "should get the #{val} attribute" do attributes = mock("attributes") attributes.expects(:[]).with(val) @provider.stubs(:user_attributes).returns(attributes) @provider.send(val) end end end describe "when getting the keys" do it "should get the user_attributes" do @provider.expects(:user_attributes) @provider.keys end it "should call removed_managed_attributes" do @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" }) @provider.expects(:remove_managed_attributes) @provider.keys end it "should removed managed attribute (type, auths, roles, etc)" do @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" }) @provider.keys.should == { :foo => "something" } end end describe "when adding properties" do it "should call build_keys_cmd" do @resource.stubs(:should).returns "" @resource.expects(:should).with(:keys).returns({ :foo => "bar" }) @provider.expects(:build_keys_cmd).returns([]) @provider.add_properties end it "should add the elements of the keys hash to an array" do @resource.stubs(:should).returns "" @resource.expects(:should).with(:keys).returns({ :foo => "bar"}) @provider.add_properties.must == ["-K", "foo=bar"] end end describe "when calling build_keys_cmd" do it "should build cmd array with keypairs seperated by -K ending with user" do @provider.build_keys_cmd({"foo" => "bar", "baz" => "boo"}).should.eql? ["-K", "foo=bar", "-K", "baz=boo"] end end describe "when setting the keys" do before do @provider.stubs(:is_role?).returns(false) end it "should run a command" do @provider.expects(:run) @provider.keys=({}) end it "should build the command" do @resource.stubs(:[]).with(:name).returns("someuser") @provider.stubs(:command).returns("usermod") @provider.expects(:build_keys_cmd).returns(["-K", "foo=bar"]) @provider.expects(:run).with(["usermod", "-K", "foo=bar", "someuser"], "modify attribute key pairs") @provider.keys=({}) end end describe "when getting the hashed password" do before do @array = mock "array" end it "should readlines of /etc/shadow" do File.expects(:readlines).with("/etc/shadow").returns([]) @provider.password end it "should reject anything that doesn't start with alpha numerics" do @array.expects(:reject).returns([]) File.stubs(:readlines).with("/etc/shadow").returns(@array) @provider.password end it "should collect splitting on ':'" do @array.stubs(:reject).returns(@array) @array.expects(:collect).returns([]) File.stubs(:readlines).with("/etc/shadow").returns(@array) @provider.password end it "should find the matching user" do @resource.stubs(:[]).with(:name).returns("username") @array.stubs(:reject).returns(@array) @array.stubs(:collect).returns([["username", "hashedpassword"], ["someoneelse", "theirpassword"]]) File.stubs(:readlines).with("/etc/shadow").returns(@array) @provider.password.must == "hashedpassword" end it "should get the right password" do @resource.stubs(:[]).with(:name).returns("username") File.stubs(:readlines).with("/etc/shadow").returns(["#comment", " nonsense", " ", "username:hashedpassword:stuff:foo:bar:::", "other:pword:yay:::"]) @provider.password.must == "hashedpassword" end end describe "when setting the password" do let(:path) { tmpfile('etc-shadow') } before :each do @provider.stubs(:target_file_path).returns(path) end def write_fixture(content) File.open(path, 'w') { |f| f.print(content) } end it "should update the target user" do write_fixture < "mypool") - @resource.stubs(:[]).returns "shouldvalue" + @resource.stubs(:[]).returns ["shouldvalue"] @provider = provider_class.new(@resource) end describe "when getting the instance" do it "should call process_zpool_data with the result of get_pool_data only once" do @provider.stubs(:get_pool_data).returns(["foo", "disk"]) @provider.expects(:process_zpool_data).with(["foo", "disk"]).returns("stuff").once @provider.current_pool @provider.current_pool end end describe "when calling flush" do it "should need to reload the pool" do @provider.stubs(:get_pool_data) @provider.expects(:process_zpool_data).returns("stuff").times(2) @provider.current_pool @provider.flush @provider.current_pool end end describe "when procesing zpool data" do before do @zpool_data = ["foo", "disk"] end describe "when there is no data" do it "should return a hash with ensure=>:absent" do @provider.process_zpool_data([])[:ensure].should == :absent end end describe "when there is a spare" do it "should add the spare disk to the hash" do @zpool_data += ["spares", "spare_disk"] @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk"] end end describe "when there are two spares" do it "should add the spare disk to the hash as a single string" do @zpool_data += ["spares", "spare_disk", "spare_disk2"] @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk spare_disk2"] end end describe "when there is a log" do it "should add the log disk to the hash" do @zpool_data += ["logs", "log_disk"] @provider.process_zpool_data(@zpool_data)[:log].should == ["log_disk"] end end describe "when there are two logs" do it "should add the log disks to the hash as a single string" do @zpool_data += ["spares", "spare_disk", "spare_disk2"] @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk spare_disk2"] end end describe "when the vdev is a single mirror" do it "should call create_multi_array with mirror" do @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2"] @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2"] end end describe "when the vdev is a single mirror on solaris 10u9 or later" do it "should call create_multi_array with mirror" do @zpool_data = ["mirrorpool", "mirror-0", "disk1", "disk2"] @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2"] end end describe "when the vdev is a double mirror" do it "should call create_multi_array with mirror" do @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2", "mirror", "disk3", "disk4"] @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2", "disk3 disk4"] end end describe "when the vdev is a double mirror on solaris 10u9 or later" do it "should call create_multi_array with mirror" do @zpool_data = ["mirrorpool", "mirror-0", "disk1", "disk2", "mirror-1", "disk3", "disk4"] @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2", "disk3 disk4"] end end describe "when the vdev is a raidz1" do it "should call create_multi_array with raidz1" do @zpool_data = ["mirrorpool", "raidz1", "disk1", "disk2"] @provider.process_zpool_data(@zpool_data)[:raidz].should == ["disk1 disk2"] end end describe "when the vdev is a raidz1 on solaris 10u9 or later" do it "should call create_multi_array with raidz1" do @zpool_data = ["mirrorpool", "raidz1-0", "disk1", "disk2"] @provider.process_zpool_data(@zpool_data)[:raidz].should == ["disk1 disk2"] end end describe "when the vdev is a raidz2" do it "should call create_multi_array with raidz2 and set the raid_parity" do @zpool_data = ["mirrorpool", "raidz2", "disk1", "disk2"] pool = @provider.process_zpool_data(@zpool_data) pool[:raidz].should == ["disk1 disk2"] pool[:raid_parity].should == "raidz2" end end describe "when the vdev is a raidz2 on solaris 10u9 or later" do it "should call create_multi_array with raidz2 and set the raid_parity" do @zpool_data = ["mirrorpool", "raidz2-0", "disk1", "disk2"] pool = @provider.process_zpool_data(@zpool_data) pool[:raidz].should == ["disk1 disk2"] pool[:raid_parity].should == "raidz2" end end end describe "when calling the getters and setters" do [:disk, :mirror, :raidz, :log, :spare].each do |field| describe "when calling #{field}" do it "should get the #{field} value from the current_pool hash" do pool_hash = mock "pool hash" pool_hash.expects(:[]).with(field) @provider.stubs(:current_pool).returns(pool_hash) @provider.send(field) end end describe "when setting the #{field}" do it "should warn the #{field} values were not in sync" do Puppet.expects(:warning).with("NO CHANGES BEING MADE: zpool #{field} does not match, should be 'shouldvalue' currently is 'currentvalue'") @provider.stubs(:current_pool).returns(Hash.new("currentvalue")) @provider.send((field.to_s + "=").intern, "shouldvalue") end end end end - describe "when calling create", :'fails_on_ruby_1.9.2' => true do + describe "when calling create" do before do @resource.stubs(:[]).with(:pool).returns("mypool") @provider.stubs(:zpool) end it "should call build_vdevs" do @provider.expects(:build_vdevs).returns([]) @provider.create end it "should call build_named with 'spares' and 'log" do @provider.expects(:build_named).with("spare").returns([]) @provider.expects(:build_named).with("log").returns([]) @provider.create end it "should call zpool with arguments from build_vdevs and build_named" do @provider.expects(:zpool).with(:create, 'mypool', 'shouldvalue', 'spare', 'shouldvalue', 'log', 'shouldvalue') @provider.create end end describe "when calling delete" do it "should call zpool with destroy and the pool name" do @resource.stubs(:[]).with(:pool).returns("poolname") @provider.expects(:zpool).with(:destroy, "poolname") @provider.delete end end describe "when calling exists?" do before do @current_pool = Hash.new(:absent) @provider.stubs(:get_pool_data).returns([]) @provider.stubs(:process_zpool_data).returns(@current_pool) end it "should get the current pool" do @provider.expects(:process_zpool_data).returns(@current_pool) @provider.exists? end it "should return false if the current_pool is absent" do #the before sets it up @provider.exists?.should == false end it "should return true if the current_pool has values" do @current_pool[:pool] = "mypool" @provider.exists?.should == true end end end diff --git a/spec/unit/provider_spec.rb b/spec/unit/provider_spec.rb index eeda5dff9..100536d93 100755 --- a/spec/unit/provider_spec.rb +++ b/spec/unit/provider_spec.rb @@ -1,62 +1,450 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Provider do - it "should have a specifity class method" do - Puppet::Provider.should respond_to(:specificity) + before :each do + Puppet::Type.newtype(:test) do + newparam(:name) { isnamevar } + end end - it "should consider two defaults to be higher specificity than one default" do - one = Class.new(Puppet::Provider) - one.initvars - one.defaultfor :operatingsystem => "solaris" - - two = Class.new(Puppet::Provider) - two.initvars - two.defaultfor :operatingsystem => "solaris", :operatingsystemrelease => "5.10" - - two.specificity.should > one.specificity + after :each do + Puppet::Type.rmtype(:test) end - it "should consider a subclass more specific than its parent class" do - one = Class.new(Puppet::Provider) - one.initvars + let :type do Puppet::Type.type(:test) end + let :provider do type.provide(:default) {} end - two = Class.new(one) - two.initvars + subject { provider } - two.specificity.should > one.specificity - end it "should be Comparable" do res = Puppet::Type.type(:notify).new(:name => "res") # Normally I wouldn't like the stubs, but the only way to name a class # otherwise is to assign it to a constant, and that hurts more here in # testing world. --daniel 2012-01-29 a = Class.new(Puppet::Provider).new(res) a.class.stubs(:name).returns "Puppet::Provider::Notify::A" b = Class.new(Puppet::Provider).new(res) b.class.stubs(:name).returns "Puppet::Provider::Notify::B" c = Class.new(Puppet::Provider).new(res) c.class.stubs(:name).returns "Puppet::Provider::Notify::C" [[a, b, c], [a, c, b], [b, a, c], [b, c, a], [c, a, b], [c, b, a]].each do |this| this.sort.should == [a, b, c] end a.should be < b a.should be < c b.should be > a b.should be < c c.should be > a c.should be > b [a, b, c].each {|x| a.should be <= x } [a, b, c].each {|x| c.should be >= x } b.should be_between(a, c) end + + context "when creating instances" do + context "with a resource" do + let :resource do type.new(:name => "fred") end + subject { provider.new(resource) } + + it "should set the resource correctly" do + subject.resource.must equal resource + end + + it "should set the name from the resource" do + subject.name.should == resource.name + end + end + + context "with a hash" do + subject { provider.new(:name => "fred") } + + it "should set the name" do + subject.name.should == "fred" + end + + it "should not have a resource" do subject.resource.should be_nil end + end + + context "with no arguments" do + subject { provider.new } + + it "should raise an internal error if asked for the name" do + expect { subject.name }.to raise_error Puppet::DevError + end + + it "should not have a resource" do subject.resource.should be_nil end + end + end + + context "when confining" do + it "should be suitable by default" do + subject.should be_suitable + end + + it "should not be default by default" do + subject.should_not be_default + end + + { { :true => true } => true, + { :true => false } => false, + { :false => false } => true, + { :false => true } => false, + { :operatingsystem => Facter.value(:operatingsystem) } => true, + { :operatingsystem => :yayness } => false, + { :nothing => :yayness } => false, + { :exists => Puppet::Util.which("echo") } => true, + { :exists => "/this/file/does/not/exist" } => false, + { :true => true, :exists => Puppet::Util.which("echo") } => true, + { :true => true, :exists => "/this/file/does/not/exist" } => false, + { :operatingsystem => Facter.value(:operatingsystem), + :exists => Puppet::Util.which("echo") } => true, + { :operatingsystem => :yayness, + :exists => Puppet::Util.which("echo") } => false, + { :operatingsystem => Facter.value(:operatingsystem), + :exists => "/this/file/does/not/exist" } => false, + { :operatingsystem => :yayness, + :exists => "/this/file/does/not/exist" } => false, + }.each do |confines, result| + it "should confine #{confines.inspect} to #{result}" do + confines.each {|test, value| subject.confine test => value } + subject.send(result ? :should : :should_not, be_suitable) + end + end + + it "should not override a confine even if a second has the same type" do + subject.confine :true => false + subject.should_not be_suitable + + subject.confine :true => true + subject.should_not be_suitable + end + + it "should not be suitable if any confine fails" do + subject.confine :true => false + subject.should_not be_suitable + + 10.times do + subject.confine :true => true + subject.should_not be_suitable + end + end + + end + + context "default providers" do + let :os do Facter.value(:operatingsystem) end + + it { should respond_to :specificity } + + it "should find the default provider" do + type.provide(:nondefault) {} + subject.defaultfor :operatingsystem => os + subject.name.should == type.defaultprovider.name + end + + it "should consider any true value enough to be default" do + alternate = type.provide(:alternate) {} + + subject.defaultfor :operatingsystem => [:one, :two, :three, os] + subject.name.should == type.defaultprovider.name + + subject.should be_default + alternate.should_not be_default + end + + it "should not be default if the confine doesn't match" do + subject.should_not be_default + subject.defaultfor :operatingsystem => :one + subject.should_not be_default + end + + it "should consider two defaults to be higher specificity than one default" do + one = type.provide(:one) do + defaultfor :operatingsystem => "solaris" + end + + two = type.provide(:two) do + defaultfor :operatingsystem => "solaris", :operatingsystemrelease => "5.10" + end + + two.specificity.should > one.specificity + end + + it "should consider a subclass more specific than its parent class" do + parent = type.provide(:parent) + child = type.provide(:child, :parent => parent) + + child.specificity.should > parent.specificity + end + end + + context "provider commands" do + it "should raise for unknown commands" do + expect { subject.command(:something) }.to raise_error Puppet::DevError + end + + it "should handle command inheritance" do + parent = type.provide("parent") + child = type.provide("child", :parent => parent.name) + + command = Puppet::Util.which('sh') || Puppet::Util.which('cmd.exe') + parent.commands :sh => command + + FileTest.should be_exists parent.command(:sh) + parent.command(:sh).should =~ /#{command}$/ + + FileTest.should be_exists child.command(:sh) + child.command(:sh).should =~ /#{command}$/ + end + + it "#1197: should find commands added in the same run" do + subject.commands :testing => "puppet-bug-1197" + subject.command(:testing).should be_nil + + subject.stubs(:which).with("puppet-bug-1197").returns("/puppet-bug-1197") + subject.command(:testing).should == "/puppet-bug-1197" + + # Ideally, we would also test that `suitable?` returned the right thing + # here, but it is impossible to get access to the methods that do that + # without digging way down into the implementation. --daniel 2012-03-20 + end + + context "with optional commands" do + before :each do + subject.optional_commands :cmd => "/no/such/binary/exists" + end + + it { should be_suitable } + + it "should not be suitable if a mandatory command is also missing" do + subject.commands :foo => "/no/such/binary/either" + subject.should_not be_suitable + end + + it "should define a wrapper for the command" do + subject.should respond_to :cmd + end + + it "should return nil if the command is requested" do + subject.command(:cmd).should be_nil + end + + it "should raise if the command is invoked" do + expect { subject.cmd }.to raise_error Puppet::Error, /Command cmd is missing/ + end + end + end + + context "mk_resource_methods" do + before :each do + type.newproperty(:prop1) + type.newproperty(:prop2) + type.newparam(:param1) + type.newparam(:param2) + end + + fields = %w{prop1 prop2 param1 param2} + + # This is needed for Ruby 1.8.5, which throws an exception that the + # default rescue doesn't catch if the method isn't present. Also, it has + # no convenient predicate for them, which equally hurts. + def has_method?(object, name) + begin + return true if object.instance_method(name) + rescue Exception + return false + end + end + + fields.each do |name| + it "should add getter methods for #{name}" do + expect { subject.mk_resource_methods }. + to change { has_method?(subject, name) }. + from(false).to(true) + end + + it "should add setter methods for #{name}" do + method = name + '=' + expect { subject.mk_resource_methods }. + to change { has_method?(subject, name) }. + from(false).to(true) + end + end + + context "with an instance" do + subject { provider.mk_resource_methods; provider.new(nil) } + + fields.each do |name| + context name do + it "should default to :absent" do + subject.send(name).should == :absent + end + + it "should update when set" do + expect { subject.send(name + '=', "hello") }. + to change { subject.send(name) }. + from(:absent).to("hello") + end + end + end + end + end + + context "source" do + it "should default to the provider name" do + subject.source.should == :default + end + + it "should default to the provider name for a child provider" do + type.provide(:sub, :parent => subject.name).source.should == :sub + end + + it "should override if requested" do + provider = type.provide(:sub, :parent => subject.name, :source => subject.source) + provider.source.should == subject.source + end + + it "should override to anything you want" do + expect { subject.source = :banana }.to change { subject.source }. + from(:default).to(:banana) + end + end + + context "features" do + before :each do + type.feature :numeric, '', :methods => [:one, :two] + type.feature :alpha, '', :methods => [:a, :b] + type.feature :nomethods, '' + end + + { :no => { :alpha => false, :numeric => false, :methods => [] }, + :numeric => { :alpha => false, :numeric => true, :methods => [:one, :two] }, + :alpha => { :alpha => true, :numeric => false, :methods => [:a, :b] }, + :all => { + :alpha => true, :numeric => true, + :methods => [:a, :b, :one, :two] + }, + :alpha_and_partial => { + :alpha => true, :numeric => false, + :methods => [:a, :b, :one] + }, + :numeric_and_partial => { + :alpha => false, :numeric => true, + :methods => [:a, :one, :two] + }, + :all_partial => { :alpha => false, :numeric => false, :methods => [:a, :one] }, + :other_and_none => { :alpha => false, :numeric => false, :methods => [:foo, :bar] }, + :other_and_alpha => { + :alpha => true, :numeric => false, + :methods => [:foo, :bar, :a, :b] + }, + }.each do |name, setup| + context "with #{name.to_s.gsub('_', ' ')} features" do + let :provider do + provider = type.provide(name) + setup[:methods].map do |method| + provider.send(:define_method, method) do true end + end + type.provider(name) + end + + let :numeric? do setup[:numeric] ? :should : :should_not end + let :alpha? do setup[:alpha] ? :should : :should_not end + + subject { provider } + + it { should respond_to :has_features } + it { should respond_to :has_feature } + + context "provider class" do + it { should respond_to :nomethods? } + it { should_not be_nomethods } + + it { should respond_to :numeric? } + it { subject.send(numeric?, be_numeric) } + it { subject.send(numeric?, be_satisfies(:numeric)) } + + it { should respond_to :alpha? } + it { subject.send(alpha?, be_alpha) } + it { subject.send(alpha?, be_satisfies(:alpha)) } + end + + context "provider instance" do + subject { provider.new } + + it { should respond_to :numeric? } + it { subject.send(numeric?, be_numeric) } + it { subject.send(numeric?, be_satisfies(:numeric)) } + + it { should respond_to :alpha? } + it { subject.send(alpha?, be_alpha) } + it { subject.send(alpha?, be_satisfies(:alpha)) } + end + end + end + + context "feature with no methods" do + before :each do + type.feature :undemanding, '' + end + + it { should respond_to :undemanding? } + + context "when the feature is not declared" do + it { should_not be_undemanding } + it { should_not be_satisfies :undemanding } + end + + context "when the feature is declared" do + before :each do + subject.has_feature :undemanding + end + + it { should be_undemanding } + it { should be_satisfies :undemanding } + end + end + + context "supports_parameter?" do + before :each do + type.newparam(:no_feature) + type.newparam(:one_feature, :required_features => :alpha) + type.newparam(:two_features, :required_features => [:alpha, :numeric]) + end + + let :providers do + { + :zero => type.provide(:zero), + :one => type.provide(:one) do has_features :alpha end, + :two => type.provide(:two) do has_features :alpha, :numeric end + } + end + + { :zero => { :yes => [:no_feature], :no => [:one_feature, :two_features] }, + :one => { :yes => [:no_feature, :one_feature], :no => [:two_features] }, + :two => { :yes => [:no_feature, :one_feature, :two_features], :no => [] } + }.each do |name, data| + data[:yes].each do |param| + it "should support #{param} with provider #{name}" do + providers[name].should be_supports_parameter param + end + end + + data[:no].each do |param| + it "should not support #{param} with provider #{name}" do + providers[name].should_not be_supports_parameter param + end + end + end + end + end end diff --git a/spec/unit/puppet_spec.rb b/spec/unit/puppet_spec.rb index 50d3a4718..33fb2be2e 100755 --- a/spec/unit/puppet_spec.rb +++ b/spec/unit/puppet_spec.rb @@ -1,12 +1,45 @@ #!/usr/bin/env rspec" - require 'spec_helper' require 'puppet' +require 'puppet_spec/files' +require 'semver' describe Puppet do + include PuppetSpec::Files + + context "#version" do + it "should be a valid version number" do + Puppet.version.should =~ /^[0-9]+\.[0-9]+\.[0-9]+$/ + end + + it "should be valid semver" do + SemVer.should be_valid Puppet.version + end + end + Puppet::Util::Log.eachlevel do |level| it "should have a method for sending '#{level}' logs" do Puppet.should respond_to(level) end end + + it "should be able to change the path" do + newpath = ENV["PATH"] + ":/something/else" + Puppet[:path] = newpath + ENV["PATH"].should == newpath + end + + it "should change $LOAD_PATH when :libdir changes" do + one = tmpdir('load-path-one') + two = tmpdir('load-path-two') + one.should_not == two + + Puppet[:libdir] = one + $LOAD_PATH.should include one + $LOAD_PATH.should_not include two + + Puppet[:libdir] = two + $LOAD_PATH.should_not include one + $LOAD_PATH.should include two + end end diff --git a/spec/unit/resource/status_spec.rb b/spec/unit/resource/status_spec.rb index 18e3359df..967708432 100755 --- a/spec/unit/resource/status_spec.rb +++ b/spec/unit/resource/status_spec.rb @@ -1,154 +1,154 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/resource/status' describe Puppet::Resource::Status do include PuppetSpec::Files before do @resource = Puppet::Type.type(:file).new :path => make_absolute("/my/file") @status = Puppet::Resource::Status.new(@resource) end it "should compute type and title correctly" do @status.resource_type.should == "File" @status.title.should == make_absolute("/my/file") end [:node, :file, :line, :current_values, :status, :evaluation_time].each do |attr| it "should support #{attr}" do @status.send(attr.to_s + "=", "foo") @status.send(attr).should == "foo" end end [:skipped, :failed, :restarted, :failed_to_restart, :changed, :out_of_sync, :scheduled].each do |attr| it "should support #{attr}" do @status.send(attr.to_s + "=", "foo") @status.send(attr).should == "foo" end it "should have a boolean method for determining whehter it was #{attr}" do @status.send(attr.to_s + "=", "foo") @status.should send("be_#{attr}") end end it "should accept a resource at initialization" do Puppet::Resource::Status.new(@resource).resource.should_not be_nil end it "should set its source description to the resource's path" do @resource.expects(:path).returns "/my/path" Puppet::Resource::Status.new(@resource).source_description.should == "/my/path" end [:file, :line].each do |attr| it "should copy the resource's #{attr}" do @resource.expects(attr).returns "foo" Puppet::Resource::Status.new(@resource).send(attr).should == "foo" end end it "should copy the resource's tags" do @resource.expects(:tags).returns %w{foo bar} Puppet::Resource::Status.new(@resource).tags.should == %w{foo bar} end it "should always convert the resource to a string" do @resource.expects(:to_s).returns "foo" Puppet::Resource::Status.new(@resource).resource.should == "foo" end it "should support tags" do Puppet::Resource::Status.ancestors.should include(Puppet::Util::Tagging) end it "should create a timestamp at its creation time" do @status.time.should be_instance_of(Time) end describe "when sending logs" do before do Puppet::Util::Log.stubs(:new) end it "should set the tags to the event tags" do Puppet::Util::Log.expects(:new).with { |args| args[:tags] == %w{one two} } @status.stubs(:tags).returns %w{one two} @status.send_log :notice, "my message" end [:file, :line].each do |attr| it "should pass the #{attr}" do Puppet::Util::Log.expects(:new).with { |args| args[attr] == "my val" } @status.send(attr.to_s + "=", "my val") @status.send_log :notice, "my message" end end it "should use the source description as the source" do Puppet::Util::Log.expects(:new).with { |args| args[:source] == "my source" } @status.stubs(:source_description).returns "my source" @status.send_log :notice, "my message" end end it "should support adding events" do event = Puppet::Transaction::Event.new(:name => :foobar) @status.add_event(event) @status.events.should == [event] end it "should use '<<' to add events" do event = Puppet::Transaction::Event.new(:name => :foobar) (@status << event).should equal(@status) @status.events.should == [event] end it "should count the number of successful events and set changed" do 3.times{ @status << Puppet::Transaction::Event.new(:status => 'success') } @status.change_count.should == 3 @status.changed.should == true @status.out_of_sync.should == true end it "should not start with any changes" do @status.change_count.should == 0 @status.changed.should == false @status.out_of_sync.should == false end it "should not treat failure, audit, or noop events as changed" do ['failure', 'audit', 'noop'].each do |s| @status << Puppet::Transaction::Event.new(:status => s) end @status.change_count.should == 0 @status.changed.should == false end it "should not treat audit events as out of sync" do @status << Puppet::Transaction::Event.new(:status => 'audit') @status.out_of_sync_count.should == 0 @status.out_of_sync.should == false end ['failure', 'noop', 'success'].each do |event_status| it "should treat #{event_status} events as out of sync" do 3.times do @status << Puppet::Transaction::Event.new(:status => event_status) end @status.out_of_sync_count.should == 3 @status.out_of_sync.should == true end end - describe "When converting to YAML", :'fails_on_ruby_1.9.2' => true do + describe "When converting to YAML" do it "should include only documented attributes" do @status.file = "/foo.rb" @status.line = 27 @status.evaluation_time = 2.7 @status.tags = %w{one two} - @status.to_yaml_properties.should == Puppet::Resource::Status::YAML_ATTRIBUTES.sort + @status.to_yaml_properties.should =~ Puppet::Resource::Status::YAML_ATTRIBUTES end end end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 4a22fc499..548322fb0 100755 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -1,826 +1,826 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/resource' describe Puppet::Resource do include PuppetSpec::Files let :basepath do make_absolute("/somepath") end [:catalog, :file, :line].each do |attr| it "should have an #{attr} attribute" do resource = Puppet::Resource.new("file", "/my/file") resource.should respond_to(attr) resource.should respond_to(attr.to_s + "=") end end it "should have a :title attribute" do Puppet::Resource.new(:user, "foo").title.should == "foo" end it "should require the type and title" do lambda { Puppet::Resource.new }.should raise_error(ArgumentError) end it "should canonize types to capitalized strings" do Puppet::Resource.new(:user, "foo").type.should == "User" end it "should canonize qualified types so all strings are capitalized" do Puppet::Resource.new("foo::bar", "foo").type.should == "Foo::Bar" end it "should tag itself with its type" do Puppet::Resource.new("file", "/f").should be_tagged("file") end it "should tag itself with its title if the title is a valid tag" do Puppet::Resource.new("user", "bar").should be_tagged("bar") end it "should not tag itself with its title if the title is a not valid tag" do Puppet::Resource.new("file", "/bar").should_not be_tagged("/bar") end it "should allow setting of attributes" do Puppet::Resource.new("file", "/bar", :file => "/foo").file.should == "/foo" Puppet::Resource.new("file", "/bar", :exported => true).should be_exported end it "should set its type to 'Class' and its title to the passed title if the passed type is :component and the title has no square brackets in it" do ref = Puppet::Resource.new(:component, "foo") ref.type.should == "Class" ref.title.should == "Foo" end it "should interpret the title as a reference and assign appropriately if the type is :component and the title contains square brackets" do ref = Puppet::Resource.new(:component, "foo::bar[yay]") ref.type.should == "Foo::Bar" ref.title.should == "yay" end it "should set the type to 'Class' if it is nil and the title contains no square brackets" do ref = Puppet::Resource.new(nil, "yay") ref.type.should == "Class" ref.title.should == "Yay" end it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains square brackets" do ref = Puppet::Resource.new(nil, "foo::bar[yay]") ref.type.should == "Foo::Bar" ref.title.should == "yay" end it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do ref = Puppet::Resource.new(nil, "foo::bar[baz[yay]]") ref.type.should == "Foo::Bar" ref.title.should =="baz[yay]" end it "should interpret the type as a reference and assign appropriately if the title is nil and the type contains square brackets" do ref = Puppet::Resource.new("foo::bar[baz]") ref.type.should == "Foo::Bar" ref.title.should =="baz" end it "should be able to extract its information from a Puppet::Type instance" do ral = Puppet::Type.type(:file).new :path => basepath+"/foo" ref = Puppet::Resource.new(ral) ref.type.should == "File" ref.title.should == basepath+"/foo" end it "should fail if the title is nil and the type is not a valid resource reference string" do expect { Puppet::Resource.new("resource-spec-foo") }.should raise_error(ArgumentError) end it 'should fail if strict is set and type does not exist' do expect { Puppet::Resource.new('resource-spec-foo', 'title', {:strict=>true}) }.should raise_error(ArgumentError, 'Invalid resource type resource-spec-foo') end it 'should fail if strict is set and class does not exist' do expect { Puppet::Resource.new('Class', 'resource-spec-foo', {:strict=>true}) }.should raise_error(ArgumentError, 'Could not find declared class resource-spec-foo') end it "should fail if the title is a hash and the type is not a valid resource reference string" do expect { Puppet::Resource.new({:type => "resource-spec-foo", :title => "bar"}) }. to raise_error ArgumentError, /Puppet::Resource.new does not take a hash/ end it "should be taggable" do Puppet::Resource.ancestors.should be_include(Puppet::Util::Tagging) end it "should have an 'exported' attribute" do resource = Puppet::Resource.new("file", "/f") resource.exported = true resource.exported.should == true resource.should be_exported end it "should support an environment attribute" do Puppet::Resource.new("file", "/my/file", :environment => :foo).environment.name.should == :foo end describe "and munging its type and title" do describe "when modeling a builtin resource" do it "should be able to find the resource type" do Puppet::Resource.new("file", "/my/file").resource_type.should equal(Puppet::Type.type(:file)) end it "should set its type to the capitalized type name" do Puppet::Resource.new("file", "/my/file").type.should == "File" end end describe "when modeling a defined resource" do describe "that exists" do before do @type = Puppet::Resource::Type.new(:definition, "foo::bar") Puppet::Node::Environment.new.known_resource_types.add @type end it "should set its type to the capitalized type name" do Puppet::Resource.new("foo::bar", "/my/file").type.should == "Foo::Bar" end it "should be able to find the resource type" do Puppet::Resource.new("foo::bar", "/my/file").resource_type.should equal(@type) end it "should set its title to the provided title" do Puppet::Resource.new("foo::bar", "/my/file").title.should == "/my/file" end end describe "that does not exist" do it "should set its resource type to the capitalized resource type name" do Puppet::Resource.new("foo::bar", "/my/file").type.should == "Foo::Bar" end end end describe "when modeling a node" do # Life's easier with nodes, because they can't be qualified. it "should set its type to 'Node' and its title to the provided title" do node = Puppet::Resource.new("node", "foo") node.type.should == "Node" node.title.should == "foo" end end describe "when modeling a class" do it "should set its type to 'Class'" do Puppet::Resource.new("class", "foo").type.should == "Class" end describe "that exists" do before do @type = Puppet::Resource::Type.new(:hostclass, "foo::bar") Puppet::Node::Environment.new.known_resource_types.add @type end it "should set its title to the capitalized, fully qualified resource type" do Puppet::Resource.new("class", "foo::bar").title.should == "Foo::Bar" end it "should be able to find the resource type" do Puppet::Resource.new("class", "foo::bar").resource_type.should equal(@type) end end describe "that does not exist" do it "should set its type to 'Class' and its title to the capitalized provided name" do klass = Puppet::Resource.new("class", "foo::bar") klass.type.should == "Class" klass.title.should == "Foo::Bar" end end describe "and its name is set to the empty string" do it "should set its title to :main" do Puppet::Resource.new("class", "").title.should == :main end describe "and a class exists whose name is the empty string" do # this was a bit tough to track down it "should set its title to :main" do @type = Puppet::Resource::Type.new(:hostclass, "") Puppet::Node::Environment.new.known_resource_types.add @type Puppet::Resource.new("class", "").title.should == :main end end end describe "and its name is set to :main" do it "should set its title to :main" do Puppet::Resource.new("class", :main).title.should == :main end describe "and a class exists whose name is the empty string" do # this was a bit tough to track down it "should set its title to :main" do @type = Puppet::Resource::Type.new(:hostclass, "") Puppet::Node::Environment.new.known_resource_types.add @type Puppet::Resource.new("class", :main).title.should == :main end end end end end it "should return nil when looking up resource types that don't exist" do Puppet::Resource.new("foobar", "bar").resource_type.should be_nil end it "should not fail when an invalid parameter is used and strict mode is disabled" do type = Puppet::Resource::Type.new(:definition, "foobar") Puppet::Node::Environment.new.known_resource_types.add type resource = Puppet::Resource.new("foobar", "/my/file") resource[:yay] = true end it "should be considered equivalent to another resource if their type and title match and no parameters are set" do Puppet::Resource.new("file", "/f").should == Puppet::Resource.new("file", "/f") end it "should be considered equivalent to another resource if their type, title, and parameters are equal" do Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"}).should == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"}) end it "should not be considered equivalent to another resource if their type and title match but parameters are different" do Puppet::Resource.new("file", "/f", :parameters => {:fee => "baz"}).should_not == Puppet::Resource.new("file", "/f", :parameters => {:foo => "bar"}) end it "should not be considered equivalent to a non-resource" do Puppet::Resource.new("file", "/f").should_not == "foo" end it "should not be considered equivalent to another resource if their types do not match" do Puppet::Resource.new("file", "/f").should_not == Puppet::Resource.new("exec", "/f") end it "should not be considered equivalent to another resource if their titles do not match" do Puppet::Resource.new("file", "/foo").should_not == Puppet::Resource.new("file", "/f") end describe "when setting default parameters" do before do @scope = Puppet::Parser::Scope.new end it "should fail when asked to set default values and it is not a parser resource" do Puppet::Node::Environment.new.known_resource_types.add( Puppet::Resource::Type.new(:definition, "default_param", :arguments => {"a" => Puppet::Parser::AST::String.new(:value => "default")}) ) resource = Puppet::Resource.new("default_param", "name") lambda { resource.set_default_parameters(@scope) }.should raise_error(Puppet::DevError) end it "should evaluate and set any default values when no value is provided" do Puppet::Node::Environment.new.known_resource_types.add( Puppet::Resource::Type.new(:definition, "default_param", :arguments => {"a" => Puppet::Parser::AST::String.new(:value => "a_default_value")}) ) resource = Puppet::Parser::Resource.new("default_param", "name", :scope => Puppet::Parser::Scope.new) resource.set_default_parameters(@scope) resource["a"].should == "a_default_value" end it "should skip attributes with no default value" do Puppet::Node::Environment.new.known_resource_types.add( Puppet::Resource::Type.new(:definition, "no_default_param", :arguments => {"a" => Puppet::Parser::AST::String.new(:value => "a_default_value")}) ) resource = Puppet::Parser::Resource.new("no_default_param", "name", :scope => Puppet::Parser::Scope.new) lambda { resource.set_default_parameters(@scope) }.should_not raise_error end it "should return the list of default parameters set" do Puppet::Node::Environment.new.known_resource_types.add( Puppet::Resource::Type.new(:definition, "default_param", :arguments => {"a" => Puppet::Parser::AST::String.new(:value => "a_default_value")}) ) resource = Puppet::Parser::Resource.new("default_param", "name", :scope => Puppet::Parser::Scope.new) resource.set_default_parameters(@scope).should == [:a] end end describe "when validating all required parameters are present" do it "should be able to validate that all required parameters are present" do Puppet::Node::Environment.new.known_resource_types.add( Puppet::Resource::Type.new(:definition, "required_param", :arguments => {"a" => nil}) ) lambda { Puppet::Resource.new("required_param", "name").validate_complete }.should raise_error(Puppet::ParseError) end it "should not fail when all required parameters are present" do Puppet::Node::Environment.new.known_resource_types.add( Puppet::Resource::Type.new(:definition, "no_required_param") ) resource = Puppet::Resource.new("no_required_param", "name") resource["a"] = "meh" lambda { resource.validate_complete }.should_not raise_error end it "should not validate against builtin types" do lambda { Puppet::Resource.new("file", "/bar").validate_complete }.should_not raise_error end end describe "when referring to a resource with name canonicalization" do it "should canonicalize its own name" do res = Puppet::Resource.new("file", "/path/") res.uniqueness_key.should == ["/path"] res.ref.should == "File[/path/]" end end describe "when running in strict mode" do it "should be strict" do Puppet::Resource.new("file", "/path", :strict => true).should be_strict end it "should fail if invalid parameters are used" do expect { Puppet::Resource.new("file", "/path", :strict => true, :parameters => {:nosuchparam => "bar"}) }.should raise_error end it "should fail if the resource type cannot be resolved" do expect { Puppet::Resource.new("nosuchtype", "/path", :strict => true) }.should raise_error end end describe "when managing parameters" do before do @resource = Puppet::Resource.new("file", "/my/file") end it "should correctly detect when provided parameters are not valid for builtin types" do Puppet::Resource.new("file", "/my/file").should_not be_valid_parameter("foobar") end it "should correctly detect when provided parameters are valid for builtin types" do Puppet::Resource.new("file", "/my/file").should be_valid_parameter("mode") end it "should correctly detect when provided parameters are not valid for defined resource types" do type = Puppet::Resource::Type.new(:definition, "foobar") Puppet::Node::Environment.new.known_resource_types.add type Puppet::Resource.new("foobar", "/my/file").should_not be_valid_parameter("myparam") end it "should correctly detect when provided parameters are valid for defined resource types" do type = Puppet::Resource::Type.new(:definition, "foobar", :arguments => {"myparam" => nil}) Puppet::Node::Environment.new.known_resource_types.add type Puppet::Resource.new("foobar", "/my/file").should be_valid_parameter("myparam") end it "should allow setting and retrieving of parameters" do @resource[:foo] = "bar" @resource[:foo].should == "bar" end it "should allow setting of parameters at initialization" do Puppet::Resource.new("file", "/my/file", :parameters => {:foo => "bar"})[:foo].should == "bar" end it "should canonicalize retrieved parameter names to treat symbols and strings equivalently" do @resource[:foo] = "bar" @resource["foo"].should == "bar" end it "should canonicalize set parameter names to treat symbols and strings equivalently" do @resource["foo"] = "bar" @resource[:foo].should == "bar" end it "should set the namevar when asked to set the name" do resource = Puppet::Resource.new("user", "bob") Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar] resource[:name] = "bob" resource[:myvar].should == "bob" end it "should return the namevar when asked to return the name" do resource = Puppet::Resource.new("user", "bob") Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar] resource[:myvar] = "test" resource[:name].should == "test" end it "should be able to set the name for non-builtin types" do resource = Puppet::Resource.new(:foo, "bar") resource[:name] = "eh" expect { resource[:name] = "eh" }.should_not raise_error end it "should be able to return the name for non-builtin types" do resource = Puppet::Resource.new(:foo, "bar") resource[:name] = "eh" resource[:name].should == "eh" end it "should be able to iterate over parameters" do @resource[:foo] = "bar" @resource[:fee] = "bare" params = {} @resource.each do |key, value| params[key] = value end params.should == {:foo => "bar", :fee => "bare"} end it "should include Enumerable" do @resource.class.ancestors.should be_include(Enumerable) end it "should have a method for testing whether a parameter is included" do @resource[:foo] = "bar" @resource.should be_has_key(:foo) @resource.should_not be_has_key(:eh) end it "should have a method for providing the list of parameters" do @resource[:foo] = "bar" @resource[:bar] = "foo" keys = @resource.keys keys.should be_include(:foo) keys.should be_include(:bar) end it "should have a method for providing the number of parameters" do @resource[:foo] = "bar" @resource.length.should == 1 end it "should have a method for deleting parameters" do @resource[:foo] = "bar" @resource.delete(:foo) @resource[:foo].should be_nil end it "should have a method for testing whether the parameter list is empty" do @resource.should be_empty @resource[:foo] = "bar" @resource.should_not be_empty end it "should be able to produce a hash of all existing parameters" do @resource[:foo] = "bar" @resource[:fee] = "yay" hash = @resource.to_hash hash[:foo].should == "bar" hash[:fee].should == "yay" end it "should not provide direct access to the internal parameters hash when producing a hash" do hash = @resource.to_hash hash[:foo] = "bar" @resource[:foo].should be_nil end it "should use the title as the namevar to the hash if no namevar is present" do resource = Puppet::Resource.new("user", "bob") Puppet::Type.type(:user).stubs(:key_attributes).returns [:myvar] resource.to_hash[:myvar].should == "bob" end it "should set :name to the title if :name is not present for non-builtin types" do krt = Puppet::Resource::TypeCollection.new("myenv") krt.add Puppet::Resource::Type.new(:definition, :foo) resource = Puppet::Resource.new :foo, "bar" resource.stubs(:known_resource_types).returns krt resource.to_hash[:name].should == "bar" end end describe "when serializing" do before do @resource = Puppet::Resource.new("file", "/my/file") @resource["one"] = "test" @resource["two"] = "other" end it "should be able to be dumped to yaml" do proc { YAML.dump(@resource) }.should_not raise_error end it "should produce an equivalent yaml object" do text = YAML.dump(@resource) newresource = YAML.load(text) newresource.title.should == @resource.title newresource.type.should == @resource.type %w{one two}.each do |param| newresource[param].should == @resource[param] end end end describe "when loading 0.25.x storedconfigs YAML" do before :each do @old_storedconfig_yaml = %q{--- !ruby/object:Puppet::Resource::Reference builtin_type: title: /tmp/bar type: File } end it "should deserialize a Puppet::Resource::Reference without exceptions" do expect { YAML.load(@old_storedconfig_yaml) }.should_not raise_error end it "should deserialize as a Puppet::Resource::Reference as a Puppet::Resource" do YAML.load(@old_storedconfig_yaml).class.should == Puppet::Resource end it "should to_hash properly" do YAML.load(@old_storedconfig_yaml).to_hash.should == { :path => "/tmp/bar" } end end describe "when converting to a RAL resource" do it "should use the resource type's :new method to create the resource if the resource is of a builtin type" do resource = Puppet::Resource.new("file", basepath+"/my/file") result = resource.to_ral result.should be_instance_of(Puppet::Type.type(:file)) result[:path].should == basepath+"/my/file" end it "should convert to a component instance if the resource type is not of a builtin type" do resource = Puppet::Resource.new("foobar", "somename") result = resource.to_ral result.should be_instance_of(Puppet::Type.type(:component)) result.title.should == "Foobar[somename]" end end describe "when converting to puppet code" do before do @resource = Puppet::Resource.new("one::two", "/my/file", :parameters => { :noop => true, :foo => %w{one two}, :ensure => 'present', } ) end - it "should align, sort and add trailing commas to attributes with ensure first", :'fails_on_ruby_1.9.2' => true do + it "should align, sort and add trailing commas to attributes with ensure first" do @resource.to_manifest.should == <<-HEREDOC.gsub(/^\s{8}/, '').gsub(/\n$/, '') one::two { '/my/file': ensure => 'present', foo => ['one', 'two'], noop => 'true', } HEREDOC end end describe "when converting to pson", :if => Puppet.features.pson? do def pson_output_should @resource.class.expects(:pson_create).with { |hash| yield hash } end it "should include the pson util module" do Puppet::Resource.singleton_class.ancestors.should be_include(Puppet::Util::Pson) end # LAK:NOTE For all of these tests, we convert back to the resource so we can # trap the actual data structure then. it "should set its type to the provided type" do Puppet::Resource.from_pson(PSON.parse(Puppet::Resource.new("File", "/foo").to_pson)).type.should == "File" end it "should set its title to the provided title" do Puppet::Resource.from_pson(PSON.parse(Puppet::Resource.new("File", "/foo").to_pson)).title.should == "/foo" end it "should include all tags from the resource" do resource = Puppet::Resource.new("File", "/foo") resource.tag("yay") Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).tags.should == resource.tags end it "should include the file if one is set" do resource = Puppet::Resource.new("File", "/foo") resource.file = "/my/file" Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).file.should == "/my/file" end it "should include the line if one is set" do resource = Puppet::Resource.new("File", "/foo") resource.line = 50 Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).line.should == 50 end it "should include the 'exported' value if one is set" do resource = Puppet::Resource.new("File", "/foo") resource.exported = true Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).exported.should be_true end it "should set 'exported' to false if no value is set" do resource = Puppet::Resource.new("File", "/foo") Puppet::Resource.from_pson(PSON.parse(resource.to_pson)).exported.should be_false end it "should set all of its parameters as the 'parameters' entry" do resource = Puppet::Resource.new("File", "/foo") resource[:foo] = %w{bar eh} resource[:fee] = %w{baz} result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson)) result["foo"].should == %w{bar eh} result["fee"].should == %w{baz} end it "should serialize relationships as reference strings" do resource = Puppet::Resource.new("File", "/foo") resource[:requires] = Puppet::Resource.new("File", "/bar") result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson)) result[:requires].should == "File[/bar]" end it "should serialize multiple relationships as arrays of reference strings" do resource = Puppet::Resource.new("File", "/foo") resource[:requires] = [Puppet::Resource.new("File", "/bar"), Puppet::Resource.new("File", "/baz")] result = Puppet::Resource.from_pson(PSON.parse(resource.to_pson)) result[:requires].should == [ "File[/bar]", "File[/baz]" ] end end describe "when converting from pson", :if => Puppet.features.pson? do def pson_result_should Puppet::Resource.expects(:new).with { |hash| yield hash } end before do @data = { 'type' => "file", 'title' => basepath+"/yay", } end it "should set its type to the provided type" do Puppet::Resource.from_pson(@data).type.should == "File" end it "should set its title to the provided title" do Puppet::Resource.from_pson(@data).title.should == basepath+"/yay" end it "should tag the resource with any provided tags" do @data['tags'] = %w{foo bar} resource = Puppet::Resource.from_pson(@data) resource.tags.should be_include("foo") resource.tags.should be_include("bar") end it "should set its file to the provided file" do @data['file'] = "/foo/bar" Puppet::Resource.from_pson(@data).file.should == "/foo/bar" end it "should set its line to the provided line" do @data['line'] = 50 Puppet::Resource.from_pson(@data).line.should == 50 end it "should 'exported' to true if set in the pson data" do @data['exported'] = true Puppet::Resource.from_pson(@data).exported.should be_true end it "should 'exported' to false if not set in the pson data" do Puppet::Resource.from_pson(@data).exported.should be_false end it "should fail if no title is provided" do @data.delete('title') expect { Puppet::Resource.from_pson(@data) }.should raise_error(ArgumentError) end it "should fail if no type is provided" do @data.delete('type') expect { Puppet::Resource.from_pson(@data) }.should raise_error(ArgumentError) end it "should set each of the provided parameters" do @data['parameters'] = {'foo' => %w{one two}, 'fee' => %w{three four}} resource = Puppet::Resource.from_pson(@data) resource['foo'].should == %w{one two} resource['fee'].should == %w{three four} end it "should convert single-value array parameters to normal values" do @data['parameters'] = {'foo' => %w{one}} resource = Puppet::Resource.from_pson(@data) resource['foo'].should == %w{one} end end describe "it should implement to_resource" do resource = Puppet::Resource.new("file", "/my/file") resource.to_resource.should == resource end describe "because it is an indirector model" do it "should include Puppet::Indirector" do Puppet::Resource.should be_is_a(Puppet::Indirector) end it "should have a default terminus" do Puppet::Resource.indirection.terminus_class.should be end it "should have a name" do Puppet::Resource.new("file", "/my/file").name.should == "File//my/file" end end describe "when resolving resources with a catalog" do it "should resolve all resources using the catalog" do catalog = mock 'catalog' resource = Puppet::Resource.new("foo::bar", "yay") resource.catalog = catalog catalog.expects(:resource).with("Foo::Bar[yay]").returns(:myresource) resource.resolve.should == :myresource end end describe "when generating the uniqueness key" do it "should include all of the key_attributes in alphabetical order by attribute name" do Puppet::Type.type(:file).stubs(:key_attributes).returns [:myvar, :owner, :path] Puppet::Type.type(:file).stubs(:title_patterns).returns( [ [ /(.*)/, [ [:path, lambda{|x| x} ] ] ] ] ) res = Puppet::Resource.new("file", "/my/file", :parameters => {:owner => 'root', :content => 'hello'}) res.uniqueness_key.should == [ nil, 'root', '/my/file'] end end describe "#prune_parameters" do before do Puppet.newtype('blond') do newproperty(:ensure) newproperty(:height) newproperty(:weight) newproperty(:sign) newproperty(:friends) newparam(:admits_to_dying_hair) newparam(:admits_to_age) newparam(:name) end end it "should strip all parameters and strip properties that are nil, empty or absent except for ensure" do resource = Puppet::Resource.new("blond", "Bambi", :parameters => { :ensure => 'absent', :height => '', :weight => 'absent', :friends => [], :admits_to_age => true, :admits_to_dying_hair => false }) pruned_resource = resource.prune_parameters pruned_resource.should == Puppet::Resource.new("blond", "Bambi", :parameters => {:ensure => 'absent'}) end it "should leave parameters alone if in parameters_to_include" do resource = Puppet::Resource.new("blond", "Bambi", :parameters => { :admits_to_age => true, :admits_to_dying_hair => false }) pruned_resource = resource.prune_parameters(:parameters_to_include => [:admits_to_dying_hair]) pruned_resource.should == Puppet::Resource.new("blond", "Bambi", :parameters => {:admits_to_dying_hair => false}) end it "should leave properties if not nil, absent or empty" do resource = Puppet::Resource.new("blond", "Bambi", :parameters => { :ensure => 'silly', :height => '7 ft 5 in', :friends => ['Oprah'], }) pruned_resource = resource.prune_parameters pruned_resource.should == resource = Puppet::Resource.new("blond", "Bambi", :parameters => { :ensure => 'silly', :height => '7 ft 5 in', :friends => ['Oprah'], }) end end end diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb index 2cd00bda9..28f21bddd 100755 --- a/spec/unit/simple_graph_spec.rb +++ b/spec/unit/simple_graph_spec.rb @@ -1,919 +1,933 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/simple_graph' describe Puppet::SimpleGraph do it "should return the number of its vertices as its length" do @graph = Puppet::SimpleGraph.new @graph.add_vertex("one") @graph.add_vertex("two") @graph.size.should == 2 end it "should consider itself a directed graph" do Puppet::SimpleGraph.new.directed?.should be_true end it "should provide a method for reversing the graph" do @graph = Puppet::SimpleGraph.new @graph.add_edge(:one, :two) @graph.reversal.edge?(:two, :one).should be_true end it "should be able to produce a dot graph" do @graph = Puppet::SimpleGraph.new @graph.add_edge(:one, :two) proc { @graph.to_dot_graph }.should_not raise_error end describe "when managing vertices" do before do @graph = Puppet::SimpleGraph.new end it "should provide a method to add a vertex" do @graph.add_vertex(:test) @graph.vertex?(:test).should be_true end it "should reset its reversed graph when vertices are added" do rev = @graph.reversal @graph.add_vertex(:test) @graph.reversal.should_not equal(rev) end it "should ignore already-present vertices when asked to add a vertex" do @graph.add_vertex(:test) proc { @graph.add_vertex(:test) }.should_not raise_error end it "should return true when asked if a vertex is present" do @graph.add_vertex(:test) @graph.vertex?(:test).should be_true end it "should return false when asked if a non-vertex is present" do @graph.vertex?(:test).should be_false end it "should return all set vertices when asked" do @graph.add_vertex(:one) @graph.add_vertex(:two) @graph.vertices.length.should == 2 @graph.vertices.should include(:one) @graph.vertices.should include(:two) end it "should remove a given vertex when asked" do @graph.add_vertex(:one) @graph.remove_vertex!(:one) @graph.vertex?(:one).should be_false end it "should do nothing when a non-vertex is asked to be removed" do proc { @graph.remove_vertex!(:one) }.should_not raise_error end end describe "when managing edges" do before do @graph = Puppet::SimpleGraph.new end it "should provide a method to test whether a given vertex pair is an edge" do @graph.should respond_to(:edge?) end it "should reset its reversed graph when edges are added" do rev = @graph.reversal @graph.add_edge(:one, :two) @graph.reversal.should_not equal(rev) end it "should provide a method to add an edge as an instance of the edge class" do edge = Puppet::Relationship.new(:one, :two) @graph.add_edge(edge) @graph.edge?(:one, :two).should be_true end it "should provide a method to add an edge by specifying the two vertices" do @graph.add_edge(:one, :two) @graph.edge?(:one, :two).should be_true end it "should provide a method to add an edge by specifying the two vertices and a label" do @graph.add_edge(:one, :two, :callback => :awesome) @graph.edge?(:one, :two).should be_true end describe "when retrieving edges between two nodes" do it "should handle the case of nodes not in the graph" do @graph.edges_between(:one, :two).should == [] end it "should handle the case of nodes with no edges between them" do @graph.add_vertex(:one) @graph.add_vertex(:two) @graph.edges_between(:one, :two).should == [] end it "should handle the case of nodes connected by a single edge" do edge = Puppet::Relationship.new(:one, :two) @graph.add_edge(edge) @graph.edges_between(:one, :two).length.should == 1 @graph.edges_between(:one, :two)[0].should equal(edge) end it "should handle the case of nodes connected by multiple edges" do edge1 = Puppet::Relationship.new(:one, :two, :callback => :foo) edge2 = Puppet::Relationship.new(:one, :two, :callback => :bar) @graph.add_edge(edge1) @graph.add_edge(edge2) Set.new(@graph.edges_between(:one, :two)).should == Set.new([edge1, edge2]) end end it "should add the edge source as a vertex if it is not already" do edge = Puppet::Relationship.new(:one, :two) @graph.add_edge(edge) @graph.vertex?(:one).should be_true end it "should add the edge target as a vertex if it is not already" do edge = Puppet::Relationship.new(:one, :two) @graph.add_edge(edge) @graph.vertex?(:two).should be_true end it "should return all edges as edge instances when asked" do one = Puppet::Relationship.new(:one, :two) two = Puppet::Relationship.new(:two, :three) @graph.add_edge(one) @graph.add_edge(two) edges = @graph.edges edges.should be_instance_of(Array) edges.length.should == 2 edges.should include(one) edges.should include(two) end it "should remove an edge when asked" do edge = Puppet::Relationship.new(:one, :two) @graph.add_edge(edge) @graph.remove_edge!(edge) @graph.edge?(edge.source, edge.target).should be_false end it "should remove all related edges when a vertex is removed" do one = Puppet::Relationship.new(:one, :two) two = Puppet::Relationship.new(:two, :three) @graph.add_edge(one) @graph.add_edge(two) @graph.remove_vertex!(:two) @graph.edge?(:one, :two).should be_false @graph.edge?(:two, :three).should be_false @graph.edges.length.should == 0 end end describe "when finding adjacent vertices" do before do @graph = Puppet::SimpleGraph.new @one_two = Puppet::Relationship.new(:one, :two) @two_three = Puppet::Relationship.new(:two, :three) @one_three = Puppet::Relationship.new(:one, :three) @graph.add_edge(@one_two) @graph.add_edge(@one_three) @graph.add_edge(@two_three) end it "should return adjacent vertices" do adj = @graph.adjacent(:one) adj.should be_include(:three) adj.should be_include(:two) end it "should default to finding :out vertices" do @graph.adjacent(:two).should == [:three] end it "should support selecting :in vertices" do @graph.adjacent(:two, :direction => :in).should == [:one] end it "should default to returning the matching vertices as an array of vertices" do @graph.adjacent(:two).should == [:three] end it "should support returning an array of matching edges" do @graph.adjacent(:two, :type => :edges).should == [@two_three] end # Bug #2111 it "should not consider a vertex adjacent just because it was asked about previously" do @graph = Puppet::SimpleGraph.new @graph.add_vertex("a") @graph.add_vertex("b") @graph.edge?("a", "b") @graph.adjacent("a").should == [] end end describe "when clearing" do before do @graph = Puppet::SimpleGraph.new one = Puppet::Relationship.new(:one, :two) two = Puppet::Relationship.new(:two, :three) @graph.add_edge(one) @graph.add_edge(two) @graph.clear end it "should remove all vertices" do @graph.vertices.should be_empty end it "should remove all edges" do @graph.edges.should be_empty end end describe "when reversing graphs" do before do @graph = Puppet::SimpleGraph.new end it "should provide a method for reversing the graph" do @graph.add_edge(:one, :two) @graph.reversal.edge?(:two, :one).should be_true end it "should add all vertices to the reversed graph" do @graph.add_edge(:one, :two) @graph.vertex?(:one).should be_true @graph.vertex?(:two).should be_true end it "should retain labels on edges" do @graph.add_edge(:one, :two, :callback => :awesome) edge = @graph.reversal.edges_between(:two, :one)[0] edge.label.should == {:callback => :awesome} end end describe "when reporting cycles in the graph" do before do @graph = Puppet::SimpleGraph.new end # This works with `add_edges` to auto-vivify the resource instances. let :vertex do Hash.new do |hash, key| hash[key] = Puppet::Type.type(:notify).new(:name => key.to_s) end end def add_edges(hash) hash.each do |a,b| @graph.add_edge(vertex[a], vertex[b]) end end def simplify(cycles) cycles.map do |x| x.map do |y| y.to_s.match(/^Notify\[(.*)\]$/)[1] end end end it "should fail on two-vertex loops" do add_edges :a => :b, :b => :a proc { @graph.report_cycles_in_graph }.should raise_error(Puppet::Error) end it "should fail on multi-vertex loops" do add_edges :a => :b, :b => :c, :c => :a proc { @graph.report_cycles_in_graph }.should raise_error(Puppet::Error) end it "should fail when a larger tree contains a small cycle" do add_edges :a => :b, :b => :a, :c => :a, :d => :c proc { @graph.report_cycles_in_graph }.should raise_error(Puppet::Error) end it "should succeed on trees with no cycles" do add_edges :a => :b, :b => :e, :c => :a, :d => :c proc { @graph.report_cycles_in_graph }.should_not raise_error end it "should produce the correct relationship text" do add_edges :a => :b, :b => :a # cycle detection starts from a or b randomly # so we need to check for either ordering in the error message want = %r{Found 1 dependency cycle:\n\((Notify\[a\] => Notify\[b\] => Notify\[a\]|Notify\[b\] => Notify\[a\] => Notify\[b\])\)\nTry} expect { @graph.report_cycles_in_graph }.to raise_error(Puppet::Error, want) end it "cycle discovery should be the minimum cycle for a simple graph" do add_edges "a" => "b" add_edges "b" => "a" add_edges "b" => "c" cycles = nil expect { cycles = @graph.find_cycles_in_graph }.should_not raise_error simplify(cycles).should be == [["a", "b"]] end it "cycle discovery should handle two distinct cycles" do add_edges "a" => "a1", "a1" => "a" add_edges "b" => "b1", "b1" => "b" cycles = nil expect { cycles = @graph.find_cycles_in_graph }.should_not raise_error simplify(cycles).should be == [["a1", "a"], ["b1", "b"]] end it "cycle discovery should handle two cycles in a connected graph" do add_edges "a" => "b", "b" => "c", "c" => "d" add_edges "a" => "a1", "a1" => "a" add_edges "c" => "c1", "c1" => "c2", "c2" => "c3", "c3" => "c" cycles = nil expect { cycles = @graph.find_cycles_in_graph }.should_not raise_error simplify(cycles).should be == [%w{a1 a}, %w{c1 c2 c3 c}] end it "cycle discovery should handle a complicated cycle" do add_edges "a" => "b", "b" => "c" add_edges "a" => "c" add_edges "c" => "c1", "c1" => "a" add_edges "c" => "c2", "c2" => "b" cycles = nil expect { cycles = @graph.find_cycles_in_graph }.should_not raise_error simplify(cycles).should be == [%w{a b c1 c2 c}] end it "cycle discovery should not fail with large data sets" do limit = 3000 (1..(limit - 1)).each do |n| add_edges n.to_s => (n+1).to_s end cycles = nil expect { cycles = @graph.find_cycles_in_graph }.should_not raise_error simplify(cycles).should be == [] end it "path finding should work with a simple cycle" do add_edges "a" => "b", "b" => "c", "c" => "a" cycles = @graph.find_cycles_in_graph paths = @graph.paths_in_cycle(cycles.first, 100) simplify(paths).should be == [%w{a b c a}] end it "path finding should work with two independent cycles" do add_edges "a" => "b1" add_edges "a" => "b2" add_edges "b1" => "a", "b2" => "a" cycles = @graph.find_cycles_in_graph cycles.length.should be == 1 paths = @graph.paths_in_cycle(cycles.first, 100) simplify(paths).should be == [%w{a b1 a}, %w{a b2 a}] end it "path finding should prefer shorter paths in cycles" do add_edges "a" => "b", "b" => "c", "c" => "a" add_edges "b" => "a" cycles = @graph.find_cycles_in_graph cycles.length.should be == 1 paths = @graph.paths_in_cycle(cycles.first, 100) simplify(paths).should be == [%w{a b a}, %w{a b c a}] end it "path finding should respect the max_path value" do (1..20).each do |n| add_edges "a" => "b#{n}", "b#{n}" => "a" end cycles = @graph.find_cycles_in_graph cycles.length.should be == 1 (1..20).each do |n| paths = @graph.paths_in_cycle(cycles.first, n) paths.length.should be == n end paths = @graph.paths_in_cycle(cycles.first, 21) paths.length.should be == 20 end end describe "when writing dot files" do before do @graph = Puppet::SimpleGraph.new @name = :test @file = File.join(Puppet[:graphdir], @name.to_s + ".dot") end it "should only write when graphing is enabled" do File.expects(:open).with(@file).never Puppet[:graph] = false @graph.write_graph(@name) end it "should write a dot file based on the passed name" do File.expects(:open).with(@file, "w").yields(stub("file", :puts => nil)) @graph.expects(:to_dot).with("name" => @name.to_s.capitalize) Puppet[:graph] = true @graph.write_graph(@name) end after do Puppet.settings.clear end end describe Puppet::SimpleGraph do before do @graph = Puppet::SimpleGraph.new end it "should correctly clear vertices and edges when asked" do @graph.add_edge("a", "b") @graph.add_vertex "c" @graph.clear @graph.vertices.should be_empty @graph.edges.should be_empty end end - describe "when matching edges", :'fails_on_ruby_1.9.2' => true do + describe "when matching edges" do before do @graph = Puppet::SimpleGraph.new - @event = Puppet::Transaction::Event.new(:name => :yay, :resource => "a") - @none = Puppet::Transaction::Event.new(:name => :NONE, :resource => "a") + + # The Ruby 1.8 semantics for String#[] are that treating it like an + # array and asking for `"a"[:whatever]` returns `nil`. Ruby 1.9 + # enforces that your index has to be numeric. + # + # Now, the real object here, a resource, implements [] and does + # something sane, but we don't care about any of the things that get + # asked for. Right now, anyway. + # + # So, in 1.8 we could just pass a string and it worked. For 1.9 we can + # fake it well enough by stubbing out the operator to return nil no + # matter what input we give. --daniel 2012-03-11 + resource = "a" + resource.stubs(:[]) + @event = Puppet::Transaction::Event.new(:name => :yay, :resource => resource) + @none = Puppet::Transaction::Event.new(:name => :NONE, :resource => resource) @edges = {} @edges["a/b"] = Puppet::Relationship.new("a", "b", {:event => :yay, :callback => :refresh}) @edges["a/c"] = Puppet::Relationship.new("a", "c", {:event => :yay, :callback => :refresh}) @graph.add_edge(@edges["a/b"]) end it "should match edges whose source matches the source of the event" do @graph.matching_edges(@event).should == [@edges["a/b"]] end it "should match always match nothing when the event is :NONE" do @graph.matching_edges(@none).should be_empty end it "should match multiple edges" do @graph.add_edge(@edges["a/c"]) edges = @graph.matching_edges(@event) edges.should be_include(@edges["a/b"]) edges.should be_include(@edges["a/c"]) end end describe "when determining dependencies" do before do @graph = Puppet::SimpleGraph.new @graph.add_edge("a", "b") @graph.add_edge("a", "c") @graph.add_edge("b", "d") end it "should find all dependents when they are on multiple levels" do @graph.dependents("a").sort.should == %w{b c d}.sort end it "should find single dependents" do @graph.dependents("b").sort.should == %w{d}.sort end it "should return an empty array when there are no dependents" do @graph.dependents("c").sort.should == [].sort end it "should find all dependencies when they are on multiple levels" do @graph.dependencies("d").sort.should == %w{a b} end it "should find single dependencies" do @graph.dependencies("c").sort.should == %w{a} end it "should return an empty array when there are no dependencies" do @graph.dependencies("a").sort.should == [] end end require 'puppet/util/graph' class Container < Puppet::Type::Component include Puppet::Util::Graph include Enumerable attr_accessor :name def each @children.each do |c| yield c end end def initialize(name, ary) @name = name @children = ary end def push(*ary) ary.each { |c| @children.push(c)} end def to_s @name end def ref "Container[#{self}]" end end require "puppet/resource/catalog" describe "when splicing the graph" do def container_graph @one = Container.new("one", %w{a b}) @two = Container.new("two", ["c", "d"]) @three = Container.new("three", ["i", "j"]) @middle = Container.new("middle", ["e", "f", @two]) @top = Container.new("top", ["g", "h", @middle, @one, @three]) @empty = Container.new("empty", []) @whit = Puppet::Type.type(:whit) @stage = Puppet::Type.type(:stage).new(:name => "foo") @contgraph = @top.to_graph(Puppet::Resource::Catalog.new) # We have to add the container to the main graph, else it won't # be spliced in the dependency graph. @contgraph.add_vertex(@empty) end def containers @contgraph.vertices.select { |x| !x.is_a? String } end def contents_of(x) @contgraph.direct_dependents_of(x) end def dependency_graph @depgraph = Puppet::SimpleGraph.new @contgraph.vertices.each do |v| @depgraph.add_vertex(v) end # We have to specify a relationship to our empty container, else it # never makes it into the dep graph in the first place. @explicit_dependencies = {@one => @two, "f" => "c", "h" => @middle, "c" => @empty} @explicit_dependencies.each do |source, target| @depgraph.add_edge(source, target, :callback => :refresh) end end def splice @contgraph.splice!(@depgraph) end def whit_called(name) x = @depgraph.vertices.find { |v| v.is_a?(@whit) && v.name =~ /#{Regexp.escape(name)}/ } x.should_not be_nil def x.to_s "Whit[#{name}]" end def x.inspect to_s end x end def admissible_sentinel_of(x) @depgraph.vertex?(x) ? x : whit_called("admissible_#{x.ref}") end def completed_sentinel_of(x) @depgraph.vertex?(x) ? x : whit_called("completed_#{x.ref}") end before do container_graph dependency_graph splice end # This is the real heart of splicing -- replacing all containers X in our # relationship graph with a pair of whits { admissible_X and completed_X } # such that that # # 0) completed_X depends on admissible_X # 1) contents of X each depend on admissible_X # 2) completed_X depends on each on the contents of X # 3) everything which depended on X depends on completed_X # 4) admissible_X depends on everything X depended on # 5) the containers and their edges must be removed # # Note that this requires attention to the possible case of containers # which contain or depend on other containers. # # Point by point: # 0) completed_X depends on admissible_X # it "every container's completed sentinel should depend on its admissible sentinel" do containers.each { |container| @depgraph.path_between(admissible_sentinel_of(container),completed_sentinel_of(container)).should be } end # 1) contents of X each depend on admissible_X # it "all contained objects should depend on their container's admissible sentinel" do containers.each { |container| contents_of(container).each { |leaf| @depgraph.should be_edge(admissible_sentinel_of(container),admissible_sentinel_of(leaf)) } } end # 2) completed_X depends on each on the contents of X # it "completed sentinels should depend on their container's contents" do containers.each { |container| contents_of(container).each { |leaf| @depgraph.should be_edge(completed_sentinel_of(leaf),completed_sentinel_of(container)) } } end # # 3) everything which depended on X depends on completed_X # # 4) admissible_X depends on everything X depended on # 5) the containers and their edges must be removed # it "should remove all Container objects from the dependency graph" do @depgraph.vertices.find_all { |v| v.is_a?(Container) }.should be_empty end it "should remove all Stage resources from the dependency graph" do @depgraph.vertices.find_all { |v| v.is_a?(Puppet::Type.type(:stage)) }.should be_empty end it "should no longer contain anything but the non-container objects" do @depgraph.vertices.find_all { |v| ! v.is_a?(String) and ! v.is_a?(@whit)}.should be_empty end it "should retain labels on non-containment edges" do @explicit_dependencies.each { |f,t| @depgraph.edges_between(completed_sentinel_of(f),admissible_sentinel_of(t))[0].label.should == {:callback => :refresh} } end it "should not add labels to edges that have none" do @depgraph.add_edge(@two, @three) splice @depgraph.path_between("c", "i").any? {|segment| segment.all? {|e| e.label == {} }}.should be end it "should copy labels over edges that have none" do @depgraph.add_edge("c", @three, {:callback => :refresh}) splice # And make sure the label got copied. @depgraph.path_between("c", "i").flatten.select {|e| e.label == {:callback => :refresh} }.should_not be_empty end it "should not replace a label with a nil label" do # Lastly, add some new label-less edges and make sure the label stays. @depgraph.add_edge(@middle, @three) @depgraph.add_edge("c", @three, {:callback => :refresh}) splice @depgraph.path_between("c","i").flatten.select {|e| e.label == {:callback => :refresh} }.should_not be_empty end it "should copy labels to all created edges" do @depgraph.add_edge(@middle, @three) @depgraph.add_edge("c", @three, {:callback => :refresh}) splice @three.each do |child| edge = Puppet::Relationship.new("c", child) (path = @depgraph.path_between(edge.source, edge.target)).should be path.should_not be_empty path.flatten.select {|e| e.label == {:callback => :refresh} }.should_not be_empty end end end it "should serialize to YAML using the old format by default" do Puppet::SimpleGraph.use_new_yaml_format.should == false end describe "(yaml tests)" do def empty_graph(graph) end def one_vertex_graph(graph) graph.add_vertex(:a) end def graph_without_edges(graph) [:a, :b, :c].each { |x| graph.add_vertex(x) } end def one_edge_graph(graph) graph.add_edge(:a, :b) end def many_edge_graph(graph) graph.add_edge(:a, :b) graph.add_edge(:a, :c) graph.add_edge(:b, :d) graph.add_edge(:c, :d) end def labeled_edge_graph(graph) graph.add_edge(:a, :b, :callback => :foo, :event => :bar) end def overlapping_edge_graph(graph) graph.add_edge(:a, :b, :callback => :foo, :event => :bar) graph.add_edge(:a, :b, :callback => :biz, :event => :baz) end def self.all_test_graphs [:empty_graph, :one_vertex_graph, :graph_without_edges, :one_edge_graph, :many_edge_graph, :labeled_edge_graph, :overlapping_edge_graph] end def object_ids(enumerable) # Return a sorted list of the object id's of the elements of an # enumerable. enumerable.collect { |x| x.object_id }.sort end def graph_to_yaml(graph, which_format) previous_use_new_yaml_format = Puppet::SimpleGraph.use_new_yaml_format Puppet::SimpleGraph.use_new_yaml_format = (which_format == :new) ZAML.dump(graph) ensure Puppet::SimpleGraph.use_new_yaml_format = previous_use_new_yaml_format end # Test serialization of graph to YAML. [:old, :new].each do |which_format| all_test_graphs.each do |graph_to_test| - it "should be able to serialize #{graph_to_test} to YAML (#{which_format} format)" do + it "should be able to serialize #{graph_to_test} to YAML (#{which_format} format)", :if => (RUBY_VERSION[0,3] == '1.8' or YAML::ENGINE.syck?) do graph = Puppet::SimpleGraph.new send(graph_to_test, graph) yaml_form = graph_to_yaml(graph, which_format) # Hack the YAML so that objects in the Puppet namespace get # changed to YAML::DomainType objects. This lets us inspect # the serialized objects easily without invoking any # yaml_initialize hooks. yaml_form.gsub!('!ruby/object:Puppet::', '!hack/object:Puppet::') serialized_object = YAML.load(yaml_form) # Check that the object contains instance variables @edges and # @vertices only. @reversal is also permitted, but we don't # check it, because it is going to be phased out. serialized_object.type_id.should == 'object:Puppet::SimpleGraph' serialized_object.value.keys.reject { |x| x == 'reversal' }.sort.should == ['edges', 'vertices'] # Check edges by forming a set of tuples (source, target, # callback, event) based on the graph and the YAML and make sure # they match. edges = serialized_object.value['edges'] edges.should be_a(Array) expected_edge_tuples = graph.edges.collect { |edge| [edge.source, edge.target, edge.callback, edge.event] } actual_edge_tuples = edges.collect do |edge| edge.type_id.should == 'object:Puppet::Relationship' %w{source target}.each { |x| edge.value.keys.should include(x) } edge.value.keys.each { |x| ['source', 'target', 'callback', 'event'].should include(x) } %w{source target callback event}.collect { |x| edge.value[x] } end Set.new(actual_edge_tuples).should == Set.new(expected_edge_tuples) actual_edge_tuples.length.should == expected_edge_tuples.length # Check vertices one by one. vertices = serialized_object.value['vertices'] if which_format == :old vertices.should be_a(Hash) Set.new(vertices.keys).should == Set.new(graph.vertices) vertices.each do |key, value| value.type_id.should == 'object:Puppet::SimpleGraph::VertexWrapper' value.value.keys.sort.should == %w{adjacencies vertex} value.value['vertex'].should equal(key) adjacencies = value.value['adjacencies'] adjacencies.should be_a(Hash) Set.new(adjacencies.keys).should == Set.new([:in, :out]) [:in, :out].each do |direction| adjacencies[direction].should be_a(Hash) expected_adjacent_vertices = Set.new(graph.adjacent(key, :direction => direction, :type => :vertices)) Set.new(adjacencies[direction].keys).should == expected_adjacent_vertices adjacencies[direction].each do |adj_key, adj_value| # Since we already checked edges, just check consistency # with edges. desired_source = direction == :in ? adj_key : key desired_target = direction == :in ? key : adj_key expected_edges = edges.select do |edge| edge.value['source'] == desired_source && edge.value['target'] == desired_target end adj_value.should be_a(Set) if object_ids(adj_value) != object_ids(expected_edges) raise "For vertex #{key.inspect}, direction #{direction.inspect}: expected adjacencies #{expected_edges.inspect} but got #{adj_value.inspect}" end end end end else vertices.should be_a(Array) Set.new(vertices).should == Set.new(graph.vertices) vertices.length.should == graph.vertices.length end end end # Test deserialization of graph from YAML. This presumes the # correctness of serialization to YAML, which has already been # tested. all_test_graphs.each do |graph_to_test| it "should be able to deserialize #{graph_to_test} from YAML (#{which_format} format)" do reference_graph = Puppet::SimpleGraph.new send(graph_to_test, reference_graph) yaml_form = graph_to_yaml(reference_graph, which_format) recovered_graph = YAML.load(yaml_form) # Test that the recovered vertices match the vertices in the # reference graph. expected_vertices = reference_graph.vertices.to_a recovered_vertices = recovered_graph.vertices.to_a Set.new(recovered_vertices).should == Set.new(expected_vertices) recovered_vertices.length.should == expected_vertices.length # Test that the recovered edges match the edges in the # reference graph. expected_edge_tuples = reference_graph.edges.collect do |edge| [edge.source, edge.target, edge.callback, edge.event] end recovered_edge_tuples = recovered_graph.edges.collect do |edge| [edge.source, edge.target, edge.callback, edge.event] end Set.new(recovered_edge_tuples).should == Set.new(expected_edge_tuples) recovered_edge_tuples.length.should == expected_edge_tuples.length # We ought to test that the recovered graph is self-consistent # too. But we're not going to bother with that yet because # the internal representation of the graph is about to change. end end it "should be able to serialize a graph where the vertices contain backreferences to the graph (#{which_format} format)" do reference_graph = Puppet::SimpleGraph.new vertex = Object.new vertex.instance_eval { @graph = reference_graph } reference_graph.add_edge(vertex, :other_vertex) yaml_form = graph_to_yaml(reference_graph, which_format) recovered_graph = YAML.load(yaml_form) recovered_graph.vertices.length.should == 2 recovered_vertex = recovered_graph.vertices.reject { |x| x.is_a?(Symbol) }[0] recovered_vertex.instance_eval { @graph }.should equal(recovered_graph) recovered_graph.edges.length.should == 1 recovered_edge = recovered_graph.edges[0] recovered_edge.source.should equal(recovered_vertex) recovered_edge.target.should == :other_vertex end end it "should serialize properly when used as a base class" do class Puppet::TestDerivedClass < Puppet::SimpleGraph attr_accessor :foo end derived = Puppet::TestDerivedClass.new derived.add_edge(:a, :b) derived.foo = 1234 recovered_derived = YAML.load(YAML.dump(derived)) recovered_derived.class.should equal(Puppet::TestDerivedClass) recovered_derived.edges.length.should == 1 recovered_derived.edges[0].source.should == :a recovered_derived.edges[0].target.should == :b recovered_derived.vertices.length.should == 2 recovered_derived.foo.should == 1234 end end end diff --git a/spec/unit/ssl/host_spec.rb b/spec/unit/ssl/host_spec.rb index 3f94407be..fda1baa37 100755 --- a/spec/unit/ssl/host_spec.rb +++ b/spec/unit/ssl/host_spec.rb @@ -1,863 +1,863 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/ssl/host' describe Puppet::SSL::Host do include PuppetSpec::Files before do Puppet::SSL::Host.indirection.terminus_class = :file # Get a safe temporary file dir = tmpdir("ssl_host_testing") Puppet.settings[:confdir] = dir Puppet.settings[:vardir] = dir Puppet.settings.use :main, :ssl @host = Puppet::SSL::Host.new("myname") end after do # Cleaned out any cached localhost instance. Puppet::SSL::Host.reset Puppet::SSL::Host.ca_location = :none end it "should use any provided name as its name" do @host.name.should == "myname" end it "should retrieve its public key from its private key" do realkey = mock 'realkey' key = stub 'key', :content => realkey Puppet::SSL::Key.indirection.stubs(:find).returns(key) pubkey = mock 'public_key' realkey.expects(:public_key).returns pubkey @host.public_key.should equal(pubkey) end it "should default to being a non-ca host" do @host.ca?.should be_false end it "should be a ca host if its name matches the CA_NAME" do Puppet::SSL::Host.stubs(:ca_name).returns "yayca" Puppet::SSL::Host.new("yayca").should be_ca end it "should have a method for determining the CA location" do Puppet::SSL::Host.should respond_to(:ca_location) end it "should have a method for specifying the CA location" do Puppet::SSL::Host.should respond_to(:ca_location=) end it "should have a method for retrieving the default ssl host" do Puppet::SSL::Host.should respond_to(:ca_location=) end it "should have a method for producing an instance to manage the local host's keys" do Puppet::SSL::Host.should respond_to(:localhost) end it "should allow to reset localhost" do previous_host = Puppet::SSL::Host.localhost Puppet::SSL::Host.reset Puppet::SSL::Host.localhost.should_not == previous_host end it "should generate the certificate for the localhost instance if no certificate is available" do host = stub 'host', :key => nil Puppet::SSL::Host.expects(:new).returns host host.expects(:certificate).returns nil host.expects(:generate) Puppet::SSL::Host.localhost.should equal(host) end it "should create a localhost cert if no cert is available and it is a CA with autosign and it is using DNS alt names", :unless => Puppet.features.microsoft_windows? do Puppet[:autosign] = true Puppet[:confdir] = tmpdir('conf') Puppet[:dns_alt_names] = "foo,bar,baz" ca = Puppet::SSL::CertificateAuthority.new Puppet::SSL::CertificateAuthority.stubs(:instance).returns ca localhost = Puppet::SSL::Host.localhost cert = localhost.certificate cert.should be_a(Puppet::SSL::Certificate) cert.subject_alt_names.should =~ %W[DNS:#{Puppet[:certname]} DNS:foo DNS:bar DNS:baz] end context "with dns_alt_names" do before :each do @key = stub('key content') key = stub('key', :generate => true, :content => @key) Puppet::SSL::Key.stubs(:new).returns key Puppet::SSL::Key.indirection.stubs(:save).with(key) @cr = stub('certificate request') Puppet::SSL::CertificateRequest.stubs(:new).returns @cr Puppet::SSL::CertificateRequest.indirection.stubs(:save).with(@cr) end describe "explicitly specified" do before :each do Puppet[:dns_alt_names] = 'one, two' end it "should not include subjectAltName if not the local node" do @cr.expects(:generate).with(@key, {}) Puppet::SSL::Host.new('not-the-' + Puppet[:certname]).generate end it "should include subjectAltName if I am a CA" do @cr.expects(:generate). with(@key, { :dns_alt_names => Puppet[:dns_alt_names] }) Puppet::SSL::Host.localhost end end describe "implicitly defaulted" do let(:ca) { stub('ca', :sign => nil) } before :each do Puppet[:dns_alt_names] = '' Puppet::SSL::CertificateAuthority.stubs(:instance).returns ca end it "should not include defaults if we're not the CA" do Puppet::SSL::CertificateAuthority.stubs(:ca?).returns false @cr.expects(:generate).with(@key, {}) Puppet::SSL::Host.localhost end it "should not include defaults if not the local node" do Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true @cr.expects(:generate).with(@key, {}) Puppet::SSL::Host.new('not-the-' + Puppet[:certname]).generate end it "should not include defaults if we can't resolve our fqdn" do Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true Facter.stubs(:value).with(:fqdn).returns nil @cr.expects(:generate).with(@key, {}) Puppet::SSL::Host.localhost end it "should provide defaults if we're bootstrapping the local master" do Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true Facter.stubs(:value).with(:fqdn).returns 'web.foo.com' Facter.stubs(:value).with(:domain).returns 'foo.com' @cr.expects(:generate).with(@key, {:dns_alt_names => "puppet, web.foo.com, puppet.foo.com"}) Puppet::SSL::Host.localhost end end end it "should always read the key for the localhost instance in from disk" do host = stub 'host', :certificate => "eh" Puppet::SSL::Host.expects(:new).returns host host.expects(:key) Puppet::SSL::Host.localhost end it "should cache the localhost instance" do host = stub 'host', :certificate => "eh", :key => 'foo' Puppet::SSL::Host.expects(:new).once.returns host Puppet::SSL::Host.localhost.should == Puppet::SSL::Host.localhost end it "should be able to verify its certificate matches its key" do Puppet::SSL::Host.new("foo").should respond_to(:validate_certificate_with_key) end it "should consider the certificate invalid if it cannot find a key" do host = Puppet::SSL::Host.new("foo") certificate = mock('cert', :fingerprint => 'DEADBEEF') host.expects(:certificate).twice.returns certificate host.expects(:key).returns nil lambda { host.validate_certificate_with_key }.should raise_error(Puppet::Error, "No private key with which to validate certificate with fingerprint: DEADBEEF") end it "should consider the certificate invalid if it cannot find a certificate" do host = Puppet::SSL::Host.new("foo") host.expects(:key).never host.expects(:certificate).returns nil lambda { host.validate_certificate_with_key }.should raise_error(Puppet::Error, "No certificate to validate.") end it "should consider the certificate invalid if the SSL certificate's key verification fails" do host = Puppet::SSL::Host.new("foo") key = mock 'key', :content => "private_key" sslcert = mock 'sslcert' certificate = mock 'cert', {:content => sslcert, :fingerprint => 'DEADBEEF'} host.stubs(:key).returns key host.stubs(:certificate).returns certificate sslcert.expects(:check_private_key).with("private_key").returns false lambda { host.validate_certificate_with_key }.should raise_error(Puppet::Error, /DEADBEEF/) end it "should consider the certificate valid if the SSL certificate's key verification succeeds" do host = Puppet::SSL::Host.new("foo") key = mock 'key', :content => "private_key" sslcert = mock 'sslcert' certificate = mock 'cert', :content => sslcert host.stubs(:key).returns key host.stubs(:certificate).returns certificate sslcert.expects(:check_private_key).with("private_key").returns true lambda{ host.validate_certificate_with_key }.should_not raise_error end describe "when specifying the CA location" do it "should support the location ':local'" do lambda { Puppet::SSL::Host.ca_location = :local }.should_not raise_error end it "should support the location ':remote'" do lambda { Puppet::SSL::Host.ca_location = :remote }.should_not raise_error end it "should support the location ':none'" do lambda { Puppet::SSL::Host.ca_location = :none }.should_not raise_error end it "should support the location ':only'" do lambda { Puppet::SSL::Host.ca_location = :only }.should_not raise_error end it "should not support other modes" do lambda { Puppet::SSL::Host.ca_location = :whatever }.should raise_error(ArgumentError) end describe "as 'local'" do before do Puppet::SSL::Host.ca_location = :local end it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do Puppet::SSL::Certificate.indirection.cache_class.should == :file Puppet::SSL::CertificateRequest.indirection.cache_class.should == :file Puppet::SSL::CertificateRevocationList.indirection.cache_class.should == :file end it "should set the terminus class for Key and Host as :file" do Puppet::SSL::Key.indirection.terminus_class.should == :file Puppet::SSL::Host.indirection.terminus_class.should == :file end it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do Puppet::SSL::Certificate.indirection.terminus_class.should == :ca Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :ca Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :ca end end describe "as 'remote'" do before do Puppet::SSL::Host.ca_location = :remote end it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do Puppet::SSL::Certificate.indirection.cache_class.should == :file Puppet::SSL::CertificateRequest.indirection.cache_class.should == :file Puppet::SSL::CertificateRevocationList.indirection.cache_class.should == :file end it "should set the terminus class for Key as :file" do Puppet::SSL::Key.indirection.terminus_class.should == :file end it "should set the terminus class for Host, Certificate, CertificateRevocationList, and CertificateRequest as :rest" do Puppet::SSL::Host.indirection.terminus_class.should == :rest Puppet::SSL::Certificate.indirection.terminus_class.should == :rest Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :rest Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :rest end end describe "as 'only'" do before do Puppet::SSL::Host.ca_location = :only end it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do Puppet::SSL::Key.indirection.terminus_class.should == :ca Puppet::SSL::Certificate.indirection.terminus_class.should == :ca Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :ca Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :ca end it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do Puppet::SSL::Certificate.indirection.cache_class.should be_nil Puppet::SSL::CertificateRequest.indirection.cache_class.should be_nil Puppet::SSL::CertificateRevocationList.indirection.cache_class.should be_nil end it "should set the terminus class for Host to :file" do Puppet::SSL::Host.indirection.terminus_class.should == :file end end describe "as 'none'" do before do Puppet::SSL::Host.ca_location = :none end it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do Puppet::SSL::Key.indirection.terminus_class.should == :file Puppet::SSL::Certificate.indirection.terminus_class.should == :file Puppet::SSL::CertificateRequest.indirection.terminus_class.should == :file Puppet::SSL::CertificateRevocationList.indirection.terminus_class.should == :file end it "should set the terminus class for Host to 'none'" do lambda { Puppet::SSL::Host.indirection.terminus_class }.should raise_error(Puppet::DevError) end end end it "should have a class method for destroying all files related to a given host" do Puppet::SSL::Host.should respond_to(:destroy) end describe "when destroying a host's SSL files" do before do Puppet::SSL::Key.indirection.stubs(:destroy).returns false Puppet::SSL::Certificate.indirection.stubs(:destroy).returns false Puppet::SSL::CertificateRequest.indirection.stubs(:destroy).returns false end it "should destroy its certificate, certificate request, and key" do Puppet::SSL::Key.indirection.expects(:destroy).with("myhost") Puppet::SSL::Certificate.indirection.expects(:destroy).with("myhost") Puppet::SSL::CertificateRequest.indirection.expects(:destroy).with("myhost") Puppet::SSL::Host.destroy("myhost") end it "should return true if any of the classes returned true" do Puppet::SSL::Certificate.indirection.expects(:destroy).with("myhost").returns true Puppet::SSL::Host.destroy("myhost").should be_true end it "should report that nothing was deleted if none of the classes returned true" do Puppet::SSL::Host.destroy("myhost").should == "Nothing was deleted" end end describe "when initializing" do it "should default its name to the :certname setting" do Puppet.settings.expects(:value).with(:certname).returns "myname" Puppet::SSL::Host.new.name.should == "myname" end it "should downcase a passed in name" do Puppet::SSL::Host.new("Host.Domain.Com").name.should == "host.domain.com" end it "should downcase the certname if it's used" do Puppet.settings.expects(:value).with(:certname).returns "Host.Domain.Com" Puppet::SSL::Host.new.name.should == "host.domain.com" end it "should indicate that it is a CA host if its name matches the ca_name constant" do Puppet::SSL::Host.stubs(:ca_name).returns "myca" Puppet::SSL::Host.new("myca").should be_ca end end describe "when managing its private key" do before do @realkey = "mykey" @key = Puppet::SSL::Key.new("mykey") @key.content = @realkey end it "should return nil if the key is not set and cannot be found" do Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(nil) @host.key.should be_nil end it "should find the key in the Key class and return the Puppet instance" do Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(@key) @host.key.should equal(@key) end it "should be able to generate and save a new key" do Puppet::SSL::Key.expects(:new).with("myname").returns(@key) @key.expects(:generate) Puppet::SSL::Key.indirection.expects(:save) @host.generate_key.should be_true @host.key.should equal(@key) end it "should not retain keys that could not be saved" do Puppet::SSL::Key.expects(:new).with("myname").returns(@key) @key.stubs(:generate) Puppet::SSL::Key.indirection.expects(:save).raises "eh" lambda { @host.generate_key }.should raise_error @host.key.should be_nil end it "should return any previously found key without requerying" do Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(@key).once @host.key.should equal(@key) @host.key.should equal(@key) end end describe "when managing its certificate request" do before do @realrequest = "real request" @request = Puppet::SSL::CertificateRequest.new("myname") @request.content = @realrequest end it "should return nil if the key is not set and cannot be found" do Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns(nil) @host.certificate_request.should be_nil end it "should find the request in the Key class and return it and return the Puppet SSL request" do Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns @request @host.certificate_request.should equal(@request) end it "should generate a new key when generating the cert request if no key exists" do Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.expects(:key).times(2).returns(nil).then.returns(key) @host.expects(:generate_key).returns(key) @request.stubs(:generate) Puppet::SSL::CertificateRequest.indirection.stubs(:save) @host.generate_certificate_request end it "should be able to generate and save a new request using the private key" do Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.stubs(:key).returns(key) @request.expects(:generate).with("mycontent", {}) Puppet::SSL::CertificateRequest.indirection.expects(:save).with(@request) @host.generate_certificate_request.should be_true @host.certificate_request.should equal(@request) end it "should return any previously found request without requerying" do Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns(@request).once @host.certificate_request.should equal(@request) @host.certificate_request.should equal(@request) end it "should not keep its certificate request in memory if the request cannot be saved" do Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.stubs(:key).returns(key) @request.stubs(:generate) @request.stubs(:name).returns("myname") terminus = stub 'terminus' Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) terminus.expects(:save).with { |req| req.instance == @request && req.key == "myname" }.raises "eh" lambda { @host.generate_certificate_request }.should raise_error @host.instance_eval { @certificate_request }.should be_nil end end describe "when managing its certificate" do before do @realcert = mock 'certificate' @cert = stub 'cert', :content => @realcert @host.stubs(:key).returns mock("key") @host.stubs(:validate_certificate_with_key) end it "should find the CA certificate if it does not have a certificate" do Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") Puppet::SSL::Certificate.indirection.stubs(:find).with("myname").returns @cert @host.certificate end it "should not find the CA certificate if it is the CA host" do @host.expects(:ca?).returns true Puppet::SSL::Certificate.indirection.stubs(:find) Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).never @host.certificate end it "should return nil if it cannot find a CA certificate" do Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns nil Puppet::SSL::Certificate.indirection.expects(:find).with("myname").never @host.certificate.should be_nil end it "should find the key if it does not have one" do Puppet::SSL::Certificate.indirection.stubs(:find) @host.expects(:key).returns mock("key") @host.certificate end it "should generate the key if one cannot be found" do Puppet::SSL::Certificate.indirection.stubs(:find) @host.expects(:key).returns nil @host.expects(:generate_key) @host.certificate end it "should find the certificate in the Certificate class and return the Puppet certificate instance" do Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") Puppet::SSL::Certificate.indirection.expects(:find).with("myname").returns @cert @host.certificate.should equal(@cert) end it "should return any previously found certificate" do Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") Puppet::SSL::Certificate.indirection.expects(:find).with("myname").returns(@cert).once @host.certificate.should equal(@cert) @host.certificate.should equal(@cert) end end it "should have a method for listing certificate hosts" do Puppet::SSL::Host.should respond_to(:search) end describe "when listing certificate hosts" do it "should default to listing all clients with any file types" do Puppet::SSL::Key.indirection.expects(:search).returns [] Puppet::SSL::Certificate.indirection.expects(:search).returns [] Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [] Puppet::SSL::Host.search end it "should be able to list only clients with a key" do Puppet::SSL::Key.indirection.expects(:search).returns [] Puppet::SSL::Certificate.indirection.expects(:search).never Puppet::SSL::CertificateRequest.indirection.expects(:search).never Puppet::SSL::Host.search :for => Puppet::SSL::Key end it "should be able to list only clients with a certificate" do Puppet::SSL::Key.indirection.expects(:search).never Puppet::SSL::Certificate.indirection.expects(:search).returns [] Puppet::SSL::CertificateRequest.indirection.expects(:search).never Puppet::SSL::Host.search :for => Puppet::SSL::Certificate end it "should be able to list only clients with a certificate request" do Puppet::SSL::Key.indirection.expects(:search).never Puppet::SSL::Certificate.indirection.expects(:search).never Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [] Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest end - it "should return a Host instance created with the name of each found instance", :'fails_on_ruby_1.9.2' => true do + it "should return a Host instance created with the name of each found instance" do key = stub 'key', :name => "key" cert = stub 'cert', :name => "cert" csr = stub 'csr', :name => "csr" Puppet::SSL::Key.indirection.expects(:search).returns [key] Puppet::SSL::Certificate.indirection.expects(:search).returns [cert] Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [csr] returned = [] %w{key cert csr}.each do |name| result = mock(name) returned << result Puppet::SSL::Host.expects(:new).with(name).returns result end result = Puppet::SSL::Host.search returned.each do |r| result.should be_include(r) end end end it "should have a method for generating all necessary files" do Puppet::SSL::Host.new("me").should respond_to(:generate) end describe "when generating files" do before do @host = Puppet::SSL::Host.new("me") @host.stubs(:generate_key) @host.stubs(:generate_certificate_request) end it "should generate a key if one is not present" do @host.stubs(:key).returns nil @host.expects(:generate_key) @host.generate end it "should generate a certificate request if one is not present" do @host.expects(:certificate_request).returns nil @host.expects(:generate_certificate_request) @host.generate end describe "and it can create a certificate authority" do before do @ca = mock 'ca' Puppet::SSL::CertificateAuthority.stubs(:instance).returns @ca end it "should use the CA to sign its certificate request if it does not have a certificate" do @host.expects(:certificate).returns nil @ca.expects(:sign).with(@host.name, true) @host.generate end end describe "and it cannot create a certificate authority" do before do Puppet::SSL::CertificateAuthority.stubs(:instance).returns nil end it "should seek its certificate" do @host.expects(:certificate) @host.generate end end end it "should have a method for creating an SSL store" do Puppet::SSL::Host.new("me").should respond_to(:ssl_store) end it "should always return the same store" do host = Puppet::SSL::Host.new("foo") store = mock 'store' store.stub_everything OpenSSL::X509::Store.expects(:new).returns store host.ssl_store.should equal(host.ssl_store) end describe "when creating an SSL store" do before do @host = Puppet::SSL::Host.new("me") @store = mock 'store' @store.stub_everything OpenSSL::X509::Store.stubs(:new).returns @store Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing" Puppet::SSL::CertificateRevocationList.indirection.stubs(:find).returns(nil) end it "should accept a purpose" do @store.expects(:purpose=).with "my special purpose" @host.ssl_store("my special purpose") end it "should default to OpenSSL::X509::PURPOSE_ANY as the purpose" do @store.expects(:purpose=).with OpenSSL::X509::PURPOSE_ANY @host.ssl_store end it "should add the local CA cert file" do Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file" @store.expects(:add_file).with "/ca/cert/file" @host.ssl_store end describe "and a CRL is available" do before do @crl = stub 'crl', :content => "real_crl" Puppet::SSL::CertificateRevocationList.indirection.stubs(:find).returns @crl Puppet.settings.stubs(:value).with(:certificate_revocation).returns true end it "should add the CRL" do @store.expects(:add_crl).with "real_crl" @host.ssl_store end it "should set the flags to OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK" do @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK @host.ssl_store end end end describe "when waiting for a cert" do before do @host = Puppet::SSL::Host.new("me") end it "should generate its certificate request and attempt to read the certificate again if no certificate is found" do @host.expects(:certificate).times(2).returns(nil).then.returns "foo" @host.expects(:generate) @host.wait_for_cert(1) end it "should catch and log errors during CSR saving" do @host.expects(:certificate).times(2).returns(nil).then.returns "foo" @host.expects(:generate).raises(RuntimeError).then.returns nil @host.stubs(:sleep) @host.wait_for_cert(1) end it "should sleep and retry after failures saving the CSR if waitforcert is enabled" do @host.expects(:certificate).times(2).returns(nil).then.returns "foo" @host.expects(:generate).raises(RuntimeError).then.returns nil @host.expects(:sleep).with(1) @host.wait_for_cert(1) end it "should exit after failures saving the CSR of waitforcert is disabled" do @host.expects(:certificate).returns(nil) @host.expects(:generate).raises(RuntimeError) @host.expects(:puts) expect { @host.wait_for_cert(0) }.to exit_with 1 end it "should exit if the wait time is 0 and it can neither find nor retrieve a certificate" do @host.stubs(:certificate).returns nil @host.expects(:generate) @host.expects(:puts) expect { @host.wait_for_cert(0) }.to exit_with 1 end it "should sleep for the specified amount of time if no certificate is found after generating its certificate request" do @host.expects(:certificate).times(3).returns(nil).then.returns(nil).then.returns "foo" @host.expects(:generate) @host.expects(:sleep).with(1) @host.wait_for_cert(1) end it "should catch and log exceptions during certificate retrieval" do @host.expects(:certificate).times(3).returns(nil).then.raises(RuntimeError).then.returns("foo") @host.stubs(:generate) @host.stubs(:sleep) Puppet.expects(:err) @host.wait_for_cert(1) end end describe "when handling PSON", :unless => Puppet.features.microsoft_windows? do include PuppetSpec::Files before do Puppet[:vardir] = tmpdir("ssl_test_vardir") Puppet[:ssldir] = tmpdir("ssl_test_ssldir") # localcacert is where each client stores the CA certificate # cacert is where the master stores the CA certificate # Since we need to play the role of both for testing we need them to be the same and exist Puppet[:cacert] = Puppet[:localcacert] @ca=Puppet::SSL::CertificateAuthority.new end describe "when converting to PSON" do it "should be able to identify a host with an unsigned certificate request" do host = Puppet::SSL::Host.new("bazinga") host.generate_certificate_request pson_hash = { "fingerprint" => host.certificate_request.fingerprint, "desired_state" => 'requested', "name" => host.name } result = PSON.parse(Puppet::SSL::Host.new(host.name).to_pson) result["fingerprint"].should == pson_hash["fingerprint"] result["name"].should == pson_hash["name"] result["state"].should == pson_hash["desired_state"] end it "should be able to identify a host with a signed certificate" do host = Puppet::SSL::Host.new("bazinga") host.generate_certificate_request @ca.sign(host.name) pson_hash = { "fingerprint" => Puppet::SSL::Certificate.indirection.find(host.name).fingerprint, "desired_state" => 'signed', "name" => host.name, } result = PSON.parse(Puppet::SSL::Host.new(host.name).to_pson) result["fingerprint"].should == pson_hash["fingerprint"] result["name"].should == pson_hash["name"] result["state"].should == pson_hash["desired_state"] end it "should be able to identify a host with a revoked certificate" do host = Puppet::SSL::Host.new("bazinga") host.generate_certificate_request @ca.sign(host.name) @ca.revoke(host.name) pson_hash = { "fingerprint" => Puppet::SSL::Certificate.indirection.find(host.name).fingerprint, "desired_state" => 'revoked', "name" => host.name, } result = PSON.parse(Puppet::SSL::Host.new(host.name).to_pson) result["fingerprint"].should == pson_hash["fingerprint"] result["name"].should == pson_hash["name"] result["state"].should == pson_hash["desired_state"] end end describe "when converting from PSON" do it "should return a Puppet::SSL::Host object with the specified desired state" do host = Puppet::SSL::Host.new("bazinga") host.desired_state="signed" pson_hash = { "name" => host.name, "desired_state" => host.desired_state, } generated_host = Puppet::SSL::Host.from_pson(pson_hash) generated_host.desired_state.should == host.desired_state generated_host.name.should == host.name end end end end diff --git a/spec/unit/transaction/event_spec.rb b/spec/unit/transaction/event_spec.rb index 5f7f367b4..ad5c00d76 100755 --- a/spec/unit/transaction/event_spec.rb +++ b/spec/unit/transaction/event_spec.rb @@ -1,128 +1,128 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/transaction/event' describe Puppet::Transaction::Event do include PuppetSpec::Files [:previous_value, :desired_value, :property, :resource, :name, :message, :file, :line, :tags, :audited].each do |attr| - it "should support #{attr}", :'fails_on_ruby_1.9.2' => true do + it "should support #{attr}" do event = Puppet::Transaction::Event.new event.send(attr.to_s + "=", "foo") event.send(attr).should == "foo" end end it "should always convert the property to a string" do Puppet::Transaction::Event.new(:property => :foo).property.should == "foo" end - it "should always convert the resource to a string", :'fails_on_ruby_1.9.2' => true do + it "should always convert the resource to a string" do Puppet::Transaction::Event.new(:resource => :foo).resource.should == "foo" end it "should produce the message when converted to a string" do event = Puppet::Transaction::Event.new event.expects(:message).returns "my message" event.to_s.should == "my message" end it "should support 'status'" do event = Puppet::Transaction::Event.new event.status = "success" event.status.should == "success" end it "should fail if the status is not to 'audit', 'noop', 'success', or 'failure" do event = Puppet::Transaction::Event.new lambda { event.status = "foo" }.should raise_error(ArgumentError) end it "should support tags" do Puppet::Transaction::Event.ancestors.should include(Puppet::Util::Tagging) end it "should create a timestamp at its creation time" do Puppet::Transaction::Event.new.time.should be_instance_of(Time) end describe "audit property" do it "should default to false" do Puppet::Transaction::Event.new.audited.should == false end end describe "when sending logs" do before do Puppet::Util::Log.stubs(:new) end it "should set the level to the resources's log level if the event status is 'success' and a resource is available" do resource = stub 'resource' resource.expects(:[]).with(:loglevel).returns :myloglevel Puppet::Util::Log.expects(:create).with { |args| args[:level] == :myloglevel } Puppet::Transaction::Event.new(:status => "success", :resource => resource).send_log end it "should set the level to 'notice' if the event status is 'success' and no resource is available" do Puppet::Util::Log.expects(:new).with { |args| args[:level] == :notice } Puppet::Transaction::Event.new(:status => "success").send_log end it "should set the level to 'notice' if the event status is 'noop'" do Puppet::Util::Log.expects(:new).with { |args| args[:level] == :notice } Puppet::Transaction::Event.new(:status => "noop").send_log end it "should set the level to 'err' if the event status is 'failure'" do Puppet::Util::Log.expects(:new).with { |args| args[:level] == :err } Puppet::Transaction::Event.new(:status => "failure").send_log end it "should set the 'message' to the event log" do Puppet::Util::Log.expects(:new).with { |args| args[:message] == "my message" } Puppet::Transaction::Event.new(:message => "my message").send_log end it "should set the tags to the event tags" do Puppet::Util::Log.expects(:new).with { |args| args[:tags] == %w{one two} } Puppet::Transaction::Event.new(:tags => %w{one two}).send_log end [:file, :line].each do |attr| it "should pass the #{attr}" do Puppet::Util::Log.expects(:new).with { |args| args[attr] == "my val" } Puppet::Transaction::Event.new(attr => "my val").send_log end end - it "should use the source description as the source if one is set", :'fails_on_ruby_1.9.2' => true do + it "should use the source description as the source if one is set" do Puppet::Util::Log.expects(:new).with { |args| args[:source] == "/my/param" } Puppet::Transaction::Event.new(:source_description => "/my/param", :resource => "Foo[bar]", :property => "foo").send_log end - it "should use the property as the source if one is available and no source description is set", :'fails_on_ruby_1.9.2' => true do + it "should use the property as the source if one is available and no source description is set" do Puppet::Util::Log.expects(:new).with { |args| args[:source] == "foo" } Puppet::Transaction::Event.new(:resource => "Foo[bar]", :property => "foo").send_log end - it "should use the property as the source if one is available and no property or source description is set", :'fails_on_ruby_1.9.2' => true do + it "should use the property as the source if one is available and no property or source description is set" do Puppet::Util::Log.expects(:new).with { |args| args[:source] == "Foo[bar]" } Puppet::Transaction::Event.new(:resource => "Foo[bar]").send_log end end describe "When converting to YAML" do it "should include only documented attributes" do resource = Puppet::Type.type(:file).new(:title => make_absolute("/tmp/foo")) event = Puppet::Transaction::Event.new(:source_description => "/my/param", :resource => resource, :file => "/foo.rb", :line => 27, :tags => %w{one two}, :desired_value => 7, :historical_value => 'Brazil', :message => "Help I'm trapped in a spec test", :name => :mode_changed, :previous_value => 6, :property => :mode, :status => 'success') event.to_yaml_properties.should == Puppet::Transaction::Event::YAML_ATTRIBUTES.sort end end end diff --git a/spec/unit/transaction/resource_harness_spec.rb b/spec/unit/transaction/resource_harness_spec.rb index cadc31a0f..20aac576e 100755 --- a/spec/unit/transaction/resource_harness_spec.rb +++ b/spec/unit/transaction/resource_harness_spec.rb @@ -1,484 +1,484 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/transaction/resource_harness' describe Puppet::Transaction::ResourceHarness do include PuppetSpec::Files before do @mode_750 = Puppet.features.microsoft_windows? ? '644' : '750' @mode_755 = Puppet.features.microsoft_windows? ? '644' : '755' path = make_absolute("/my/file") @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new) @resource = Puppet::Type.type(:file).new :path => path @harness = Puppet::Transaction::ResourceHarness.new(@transaction) @current_state = Puppet::Resource.new(:file, path) @resource.stubs(:retrieve).returns @current_state @status = Puppet::Resource::Status.new(@resource) Puppet::Resource::Status.stubs(:new).returns @status end it "should accept a transaction at initialization" do harness = Puppet::Transaction::ResourceHarness.new(@transaction) harness.transaction.should equal(@transaction) end it "should delegate to the transaction for its relationship graph" do @transaction.expects(:relationship_graph).returns "relgraph" Puppet::Transaction::ResourceHarness.new(@transaction).relationship_graph.should == "relgraph" end describe "when evaluating a resource" do it "should create and return a resource status instance for the resource" do @harness.evaluate(@resource).should be_instance_of(Puppet::Resource::Status) end it "should fail if no status can be created" do Puppet::Resource::Status.expects(:new).raises ArgumentError lambda { @harness.evaluate(@resource) }.should raise_error end it "should retrieve the current state of the resource" do @resource.expects(:retrieve).returns @current_state @harness.evaluate(@resource) end it "should mark the resource as failed and return if the current state cannot be retrieved" do @resource.expects(:retrieve).raises ArgumentError @harness.evaluate(@resource).should be_failed end it "should store the resource's evaluation time in the resource status" do @harness.evaluate(@resource).evaluation_time.should be_instance_of(Float) end end def events_to_hash(events) events.map do |event| hash = {} event.instance_variables.each do |varname| - hash[varname] = event.instance_variable_get(varname.to_sym) + hash[varname] = event.instance_variable_get(varname) end hash end end def make_stub_provider stubProvider = Class.new(Puppet::Type) stubProvider.instance_eval do initvars newparam(:name) do desc "The name var" isnamevar end newproperty(:foo) do desc "A property that can be changed successfully" def sync end def retrieve :absent end def insync?(reference_value) false end end newproperty(:bar) do desc "A property that raises an exception when you try to change it" def sync raise ZeroDivisionError.new('bar') end def retrieve :absent end def insync?(reference_value) false end end end stubProvider end describe "when an error occurs" do before :each do stub_provider = make_stub_provider resource = stub_provider.new :name => 'name', :foo => 1, :bar => 2 resource.expects(:err).never @status = @harness.evaluate(resource) end it "should record previous successful events" do @status.events[0].property.should == 'foo' @status.events[0].status.should == 'success' end it "should record a failure event" do @status.events[1].property.should == 'bar' @status.events[1].status.should == 'failure' end end describe "when auditing" do it "should not call insync? on parameters that are merely audited" do stub_provider = make_stub_provider resource = stub_provider.new :name => 'name', :audit => ['foo'] resource.property(:foo).expects(:insync?).never status = @harness.evaluate(resource) status.events.each do |event| event.status.should != 'failure' end end it "should be able to audit a file's group" do # see bug #5710 test_file = tmpfile('foo') File.open(test_file, 'w').close resource = Puppet::Type.type(:file).new :path => test_file, :audit => ['group'], :backup => false resource.expects(:err).never # make sure no exceptions get swallowed status = @harness.evaluate(resource) status.events.each do |event| event.status.should != 'failure' end end end describe "when applying changes" do [false, true].each do |noop_mode|; describe (noop_mode ? "in noop mode" : "in normal mode") do [nil, @mode_750].each do |machine_state|; describe (machine_state ? "with a file initially present" : "with no file initially present") do [nil, @mode_750, @mode_755].each do |yaml_mode| [nil, :file, :absent].each do |yaml_ensure|; describe "with mode=#{yaml_mode.inspect} and ensure=#{yaml_ensure.inspect} stored in state.yml" do [false, true].each do |auditing_ensure| [false, true].each do |auditing_mode| auditing = [] auditing.push(:mode) if auditing_mode auditing.push(:ensure) if auditing_ensure [nil, :file, :absent].each do |ensure_property| # what we set "ensure" to in the manifest [nil, @mode_750, @mode_755].each do |mode_property| # what we set "mode" to in the manifest manifest_settings = {} manifest_settings[:audit] = auditing if !auditing.empty? manifest_settings[:ensure] = ensure_property if ensure_property manifest_settings[:mode] = mode_property if mode_property describe "with manifest settings #{manifest_settings.inspect}" do; it "should behave properly" do # Set up preconditions test_file = tmpfile('foo') if machine_state File.open(test_file, 'w', machine_state.to_i(8)).close end Puppet[:noop] = noop_mode params = { :path => test_file, :backup => false } params.merge!(manifest_settings) resource = Puppet::Type.type(:file).new params @harness.cache(resource, :mode, yaml_mode) if yaml_mode @harness.cache(resource, :ensure, yaml_ensure) if yaml_ensure fake_time = Time.utc(2011, 'jan', 3, 12, 24, 0) Time.stubs(:now).returns(fake_time) # So that Puppet::Resource::Status objects will compare properly resource.expects(:err).never # make sure no exceptions get swallowed status = @harness.evaluate(resource) # do the thing # check that the state of the machine has been properly updated expected_logs = [] expected_status_events = [] if auditing_mode @harness.cached(resource, :mode).should == (machine_state || :absent) else @harness.cached(resource, :mode).should == yaml_mode end if auditing_ensure @harness.cached(resource, :ensure).should == (machine_state ? :file : :absent) else @harness.cached(resource, :ensure).should == yaml_ensure end if ensure_property == :file file_would_be_there_if_not_noop = true elsif ensure_property == nil file_would_be_there_if_not_noop = machine_state != nil else # ensure_property == :absent file_would_be_there_if_not_noop = false end file_should_be_there = noop_mode ? machine_state != nil : file_would_be_there_if_not_noop File.exists?(test_file).should == file_should_be_there if file_should_be_there if noop_mode expected_file_mode = machine_state else expected_file_mode = mode_property || machine_state end if !expected_file_mode # we didn't specify a mode and the file was created, so mode comes from umode else file_mode = File.stat(test_file).mode & 0777 file_mode.should == expected_file_mode.to_i(8) end end # Test log output for the "mode" parameter previously_recorded_mode_already_logged = false mode_status_msg = nil if machine_state && file_would_be_there_if_not_noop && mode_property && machine_state != mode_property if noop_mode what_happened = "current_value #{machine_state}, should be #{mode_property} (noop)" expected_status = 'noop' else what_happened = "mode changed '#{machine_state}' to '#{mode_property}'" expected_status = 'success' end if auditing_mode && yaml_mode && yaml_mode != machine_state previously_recorded_mode_already_logged = true mode_status_msg = "#{what_happened} (previously recorded value was #{yaml_mode})" else mode_status_msg = what_happened end expected_logs << "notice: /#{resource}/mode: #{mode_status_msg}" end if @harness.cached(resource, :mode) && @harness.cached(resource, :mode) != yaml_mode if yaml_mode unless previously_recorded_mode_already_logged mode_status_msg = "audit change: previously recorded value #{yaml_mode} has been changed to #{@harness.cached(resource, :mode)}" expected_logs << "notice: /#{resource}/mode: #{mode_status_msg}" expected_status = 'audit' end else expected_logs << "notice: /#{resource}/mode: audit change: newly-recorded value #{@harness.cached(resource, :mode)}" end end if mode_status_msg expected_status_events << Puppet::Transaction::Event.new( :source_description => "/#{resource}/mode", :resource => resource, :file => nil, :line => nil, :tags => %w{file}, :desired_value => mode_property, :historical_value => yaml_mode, :message => mode_status_msg, :name => :mode_changed, :previous_value => machine_state || :absent, :property => :mode, :status => expected_status, :audited => auditing_mode) end # Test log output for the "ensure" parameter previously_recorded_ensure_already_logged = false ensure_status_msg = nil if file_would_be_there_if_not_noop != (machine_state != nil) if noop_mode what_happened = "current_value #{machine_state ? 'file' : 'absent'}, should be #{file_would_be_there_if_not_noop ? 'file' : 'absent'} (noop)" expected_status = 'noop' else what_happened = file_would_be_there_if_not_noop ? 'created' : 'removed' expected_status = 'success' end if auditing_ensure && yaml_ensure && yaml_ensure != (machine_state ? :file : :absent) previously_recorded_ensure_already_logged = true ensure_status_msg = "#{what_happened} (previously recorded value was #{yaml_ensure})" else ensure_status_msg = "#{what_happened}" end expected_logs << "notice: /#{resource}/ensure: #{ensure_status_msg}" end if @harness.cached(resource, :ensure) && @harness.cached(resource, :ensure) != yaml_ensure if yaml_ensure unless previously_recorded_ensure_already_logged ensure_status_msg = "audit change: previously recorded value #{yaml_ensure} has been changed to #{@harness.cached(resource, :ensure)}" expected_logs << "notice: /#{resource}/ensure: #{ensure_status_msg}" expected_status = 'audit' end else expected_logs << "notice: /#{resource}/ensure: audit change: newly-recorded value #{@harness.cached(resource, :ensure)}" end end if ensure_status_msg if ensure_property == :file ensure_event_name = :file_created elsif ensure_property == nil ensure_event_name = :file_changed else # ensure_property == :absent ensure_event_name = :file_removed end expected_status_events << Puppet::Transaction::Event.new( :source_description => "/#{resource}/ensure", :resource => resource, :file => nil, :line => nil, :tags => %w{file}, :desired_value => ensure_property, :historical_value => yaml_ensure, :message => ensure_status_msg, :name => ensure_event_name, :previous_value => machine_state ? :file : :absent, :property => :ensure, :status => expected_status, :audited => auditing_ensure) end # Actually check the logs. @logs.map {|l| "#{l.level}: #{l.source}: #{l.message}"}.should =~ expected_logs # All the log messages should show up as events except the "newly-recorded" ones. expected_event_logs = @logs.reject {|l| l.message =~ /newly-recorded/ } status.events.map {|e| e.message}.should =~ expected_event_logs.map {|l| l.message } events_to_hash(status.events).should =~ events_to_hash(expected_status_events) # Check change count - this is the number of changes that actually occurred. expected_change_count = 0 if (machine_state != nil) != file_should_be_there expected_change_count = 1 elsif machine_state != nil if expected_file_mode != machine_state expected_change_count = 1 end end status.change_count.should == expected_change_count # Check out of sync count - this is the number # of changes that would have occurred in # non-noop mode. expected_out_of_sync_count = 0 if (machine_state != nil) != file_would_be_there_if_not_noop expected_out_of_sync_count = 1 elsif machine_state != nil if mode_property != nil && mode_property != machine_state expected_out_of_sync_count = 1 end end if !noop_mode expected_out_of_sync_count.should == expected_change_count end status.out_of_sync_count.should == expected_out_of_sync_count # Check legacy summary fields status.changed.should == (expected_change_count != 0) status.out_of_sync.should == (expected_out_of_sync_count != 0) # Check the :synced field on state.yml synced_should_be_set = !noop_mode && status.changed (@harness.cached(resource, :synced) != nil).should == synced_should_be_set end; end end end end end end; end end end; end end; end it "should not apply changes if allow_changes?() returns false" do test_file = tmpfile('foo') resource = Puppet::Type.type(:file).new :path => test_file, :backup => false, :ensure => :file resource.expects(:err).never # make sure no exceptions get swallowed @harness.expects(:allow_changes?).with(resource).returns false status = @harness.evaluate(resource) File.exists?(test_file).should == false end end describe "when determining whether the resource can be changed" do before do @resource.stubs(:purging?).returns true @resource.stubs(:deleting?).returns true end it "should be true if the resource is not being purged" do @resource.expects(:purging?).returns false @harness.should be_allow_changes(@resource) end it "should be true if the resource is not being deleted" do @resource.expects(:deleting?).returns false @harness.should be_allow_changes(@resource) end it "should be true if the resource has no dependents" do @harness.relationship_graph.expects(:dependents).with(@resource).returns [] @harness.should be_allow_changes(@resource) end it "should be true if all dependents are being deleted" do dep = stub 'dependent', :deleting? => true @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep] @resource.expects(:purging?).returns true @harness.should be_allow_changes(@resource) end it "should be false if the resource's dependents are not being deleted" do dep = stub 'dependent', :deleting? => false, :ref => "myres" @resource.expects(:warning) @harness.relationship_graph.expects(:dependents).with(@resource).returns [dep] @harness.should_not be_allow_changes(@resource) end end describe "when finding the schedule" do before do @catalog = Puppet::Resource::Catalog.new @resource.catalog = @catalog end it "should warn and return nil if the resource has no catalog" do @resource.catalog = nil @resource.expects(:warning) @harness.schedule(@resource).should be_nil end it "should return nil if the resource specifies no schedule" do @harness.schedule(@resource).should be_nil end it "should fail if the named schedule cannot be found" do @resource[:schedule] = "whatever" @resource.expects(:fail) @harness.schedule(@resource) end it "should return the named schedule if it exists" do sched = Puppet::Type.type(:schedule).new(:name => "sched") @catalog.add_resource(sched) @resource[:schedule] = "sched" @harness.schedule(@resource).to_s.should == sched.to_s end end describe "when determining if a resource is scheduled" do before do @catalog = Puppet::Resource::Catalog.new @resource.catalog = @catalog @status = Puppet::Resource::Status.new(@resource) end it "should return true if 'ignoreschedules' is set" do Puppet[:ignoreschedules] = true @resource[:schedule] = "meh" @harness.should be_scheduled(@status, @resource) end it "should return true if the resource has no schedule set" do @harness.should be_scheduled(@status, @resource) end it "should return the result of matching the schedule with the cached 'checked' time if a schedule is set" do t = Time.now @harness.expects(:cached).with(@resource, :checked).returns(t) sched = Puppet::Type.type(:schedule).new(:name => "sched") @catalog.add_resource(sched) @resource[:schedule] = "sched" sched.expects(:match?).with(t.to_i).returns "feh" @harness.scheduled?(@status, @resource).should == "feh" end end it "should be able to cache data in the Storage module" do data = {} Puppet::Util::Storage.expects(:cache).with(@resource).returns data @harness.cache(@resource, :foo, "something") data[:foo].should == "something" end it "should be able to retrieve data from the cache" do data = {:foo => "other"} Puppet::Util::Storage.expects(:cache).with(@resource).returns data @harness.cached(@resource, :foo).should == "other" end end diff --git a/spec/unit/type/augeas_spec.rb b/spec/unit/type/augeas_spec.rb index e80da9559..c8dc207f9 100755 --- a/spec/unit/type/augeas_spec.rb +++ b/spec/unit/type/augeas_spec.rb @@ -1,119 +1,119 @@ #!/usr/bin/env rspec require 'spec_helper' augeas = Puppet::Type.type(:augeas) describe augeas do - describe "when augeas is present", :if => Puppet.features.augeas?, :'fails_on_ruby_1.9.2' => true do + describe "when augeas is present", :if => Puppet.features.augeas? do it "should have a default provider inheriting from Puppet::Provider" do augeas.defaultprovider.ancestors.should be_include(Puppet::Provider) end it "should have a valid provider" do augeas.new(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider) end end describe "basic structure" do it "should be able to create a instance" do provider_class = Puppet::Type::Augeas.provider(Puppet::Type::Augeas.providers[0]) Puppet::Type::Augeas.expects(:defaultprovider).returns provider_class augeas.new(:name => "bar").should_not be_nil end it "should have an parse_commands feature" do augeas.provider_feature(:parse_commands).should_not be_nil end it "should have an need_to_run? feature" do augeas.provider_feature(:need_to_run?).should_not be_nil end it "should have an execute_changes feature" do augeas.provider_feature(:execute_changes).should_not be_nil end properties = [:returns] params = [:name, :context, :onlyif, :changes, :root, :load_path, :type_check] properties.each do |property| it "should have a #{property} property" do augeas.attrclass(property).ancestors.should be_include(Puppet::Property) end it "should have documentation for its #{property} property" do augeas.attrclass(property).doc.should be_instance_of(String) end end params.each do |param| it "should have a #{param} parameter" do augeas.attrclass(param).ancestors.should be_include(Puppet::Parameter) end it "should have documentation for its #{param} parameter" do augeas.attrclass(param).doc.should be_instance_of(String) end end end describe "default values" do before do provider_class = augeas.provider(augeas.providers[0]) augeas.expects(:defaultprovider).returns provider_class end it "should be blank for context" do augeas.new(:name => :context)[:context].should == "" end it "should be blank for onlyif" do augeas.new(:name => :onlyif)[:onlyif].should == "" end it "should be blank for load_path" do augeas.new(:name => :load_path)[:load_path].should == "" end it "should be / for root" do augeas.new(:name => :root)[:root].should == "/" end it "should be false for type_check" do augeas.new(:name => :type_check)[:type_check].should == :false end end describe "provider interaction" do it "should return 0 if it does not need to run" do provider = stub("provider", :need_to_run? => false) resource = stub('resource', :resource => nil, :provider => provider, :line => nil, :file => nil) changes = augeas.attrclass(:returns).new(:resource => resource) changes.retrieve.should == 0 end it "should return :need_to_run if it needs to run" do provider = stub("provider", :need_to_run? => true) resource = stub('resource', :resource => nil, :provider => provider, :line => nil, :file => nil) changes = augeas.attrclass(:returns).new(:resource => resource) changes.retrieve.should == :need_to_run end end describe "loading specific files" do it "should require lens when incl is used" do lambda { augeas.new(:name => :no_lens, :incl => "/etc/hosts")}.should raise_error(Puppet::Error) end it "should require incl when lens is used" do lambda { augeas.new(:name => :no_incl, :lens => "Hosts.lns") }.should raise_error(Puppet::Error) end it "should set the context when a specific file is used" do fake_provider = stub_everything "fake_provider" augeas.stubs(:defaultprovider).returns fake_provider augeas.new(:name => :no_incl, :lens => "Hosts.lns", :incl => "/etc/hosts")[:context].should == "/files/etc/hosts" end end end diff --git a/spec/unit/type/exec_spec.rb b/spec/unit/type/exec_spec.rb index 0fb412b91..6b1bd0160 100755 --- a/spec/unit/type/exec_spec.rb +++ b/spec/unit/type/exec_spec.rb @@ -1,723 +1,747 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Type.type(:exec) do include PuppetSpec::Files def exec_tester(command, exitstatus = 0, rest = {}) Puppet.features.stubs(:root?).returns(true) output = rest.delete(:output) || '' tries = rest[:tries] || 1 args = { :name => command, :path => @example_path, :logoutput => false, :loglevel => :err, :returns => 0 }.merge(rest) exec = Puppet::Type.type(:exec).new(args) status = stub "process", :exitstatus => exitstatus Puppet::Util::SUIDManager.expects(:run_and_capture).times(tries). with() { |*args| args[0] == command && args[1] == nil && args[2] == nil && args[3][:override_locale] == false && args[3].has_key?(:custom_environment) } .returns([output, status]) return exec end before do @command = make_absolute('/bin/true whatever') @executable = make_absolute('/bin/true') @bogus_cmd = make_absolute('/bogus/cmd') end describe "when not stubbing the provider" do before do path = tmpdir('path') true_cmd = File.join(path, 'true') false_cmd = File.join(path, 'false') FileUtils.touch(true_cmd) FileUtils.touch(false_cmd) File.chmod(0755, true_cmd) File.chmod(0755, false_cmd) @example_path = [path] end it "should return :executed_command as its event" do resource = Puppet::Type.type(:exec).new :command => @command resource.parameter(:returns).event.name.should == :executed_command end describe "when execing" do it "should use the 'run_and_capture' method to exec" do exec_tester("true").refresh.should == :executed_command end it "should report a failure" do proc { exec_tester('false', 1).refresh }. should raise_error(Puppet::Error, /^false returned 1 instead of/) end it "should not report a failure if the exit status is specified in a returns array" do proc { exec_tester("false", 1, :returns => [0, 1]).refresh }.should_not raise_error end it "should report a failure if the exit status is not specified in a returns array" do proc { exec_tester('false', 1, :returns => [0, 100]).refresh }. should raise_error(Puppet::Error, /^false returned 1 instead of/) end it "should log the output on success" do output = "output1\noutput2\n" exec_tester('false', 0, :output => output, :logoutput => true).refresh output.split("\n").each do |line| log = @logs.shift log.level.should == :err log.message.should == line end end it "should log the output on failure" do output = "output1\noutput2\n" proc { exec_tester('false', 1, :output => output, :logoutput => true).refresh }. should raise_error(Puppet::Error) output.split("\n").each do |line| log = @logs.shift log.level.should == :err log.message.should == line end end end describe "when logoutput=>on_failure is set" do it "should log the output on failure" do output = "output1\noutput2\n" proc { exec_tester('false', 1, :output => output, :logoutput => :on_failure).refresh }. should raise_error(Puppet::Error, /^false returned 1 instead of/) output.split("\n").each do |line| log = @logs.shift log.level.should == :err log.message.should == line end end it "should log the output on failure when returns is specified as an array" do output = "output1\noutput2\n" proc { exec_tester('false', 1, :output => output, :returns => [0, 100], :logoutput => :on_failure).refresh }.should raise_error(Puppet::Error, /^false returned 1 instead of/) output.split("\n").each do |line| log = @logs.shift log.level.should == :err log.message.should == line end end it "shouldn't log the output on success" do exec_tester('true', 0, :output => "a\nb\nc\n", :logoutput => :on_failure).refresh @logs.should == [] end end it "shouldn't log the output on success when non-zero exit status is in a returns array" do exec_tester("true", 100, :output => "a\n", :logoutput => :on_failure, :returns => [1, 100]).refresh @logs.should == [] end describe " when multiple tries are set," do it "should repeat the command attempt 'tries' times on failure and produce an error" do tries = 5 resource = exec_tester("false", 1, :tries => tries, :try_sleep => 0) proc { resource.refresh }.should raise_error(Puppet::Error) end end end it "should be able to autorequire files mentioned in the command" do foo = make_absolute('/bin/foo') catalog = Puppet::Resource::Catalog.new tmp = Puppet::Type.type(:file).new(:name => foo) catalog.add_resource tmp execer = Puppet::Type.type(:exec).new(:name => foo) catalog.add_resource execer catalog.relationship_graph.dependencies(execer).should == [tmp] end describe "when handling the path parameter" do expect = %w{one two three four} { "an array" => expect, "a path-separator delimited list" => expect.join(File::PATH_SEPARATOR), "both array and path-separator delimited lists" => ["one", "two#{File::PATH_SEPARATOR}three", "four"], }.each do |test, input| it "should accept #{test}" do type = Puppet::Type.type(:exec).new(:name => @command, :path => input) type[:path].should == expect end end describe "on platforms where path separator is not :" do before :each do @old_verbosity = $VERBOSE $VERBOSE = nil @old_separator = File::PATH_SEPARATOR File::PATH_SEPARATOR = 'q' end after :each do File::PATH_SEPARATOR = @old_separator $VERBOSE = @old_verbosity end it "should use the path separator of the current platform" do type = Puppet::Type.type(:exec).new(:name => @command, :path => "fooqbarqbaz") type[:path].should == %w[foo bar baz] end end end describe "when setting user" do describe "on POSIX systems" do before :each do Puppet.features.stubs(:posix?).returns(true) Puppet.features.stubs(:microsoft_windows?).returns(false) end it "should fail if we are not root" do Puppet.features.stubs(:root?).returns(false) expect { Puppet::Type.type(:exec).new(:name => '/bin/true whatever', :user => 'input') }. should raise_error Puppet::Error, /Parameter user failed/ end ['one', 2, 'root', 4294967295, 4294967296].each do |value| it "should accept '#{value}' as user if we are root" do Puppet.features.stubs(:root?).returns(true) type = Puppet::Type.type(:exec).new(:name => '/bin/true whatever', :user => value) type[:user].should == value end end end describe "on Windows systems" do before :each do Puppet.features.stubs(:posix?).returns(false) Puppet.features.stubs(:microsoft_windows?).returns(true) Puppet.features.stubs(:root?).returns(true) end it "should reject user parameter" do expect { Puppet::Type.type(:exec).new(:name => 'c:\windows\notepad.exe', :user => 'input') }. should raise_error Puppet::Error, /Unable to execute commands as other users on Windows/ end end end describe "when setting group" do shared_examples_for "exec[:group]" do ['one', 2, 'wheel', 4294967295, 4294967296].each do |value| it "should accept '#{value}' without error or judgement" do type = Puppet::Type.type(:exec).new(:name => @command, :group => value) type[:group].should == value end end end describe "when running as root" do before :each do Puppet.features.stubs(:root?).returns(true) end it_behaves_like "exec[:group]" end describe "when not running as root" do before :each do Puppet.features.stubs(:root?).returns(false) end it_behaves_like "exec[:group]" end end describe "when setting cwd" do it_should_behave_like "all path parameters", :cwd, :array => false do def instance(path) # Specify shell provider so we don't have to care about command validation Puppet::Type.type(:exec).new(:name => @executable, :cwd => path, :provider => :shell) end end end shared_examples_for "all exec command parameters" do |param| { "relative" => "example", "absolute" => "/bin/example" }.sort.each do |name, command| describe "if command is #{name}" do before :each do @param = param end def test(command, valid) if @param == :name then instance = Puppet::Type.type(:exec).new() else instance = Puppet::Type.type(:exec).new(:name => @executable) end if valid then instance.provider.expects(:validatecmd).returns(true) else instance.provider.expects(:validatecmd).raises(Puppet::Error, "from a stub") end instance[@param] = command end it "should work if the provider calls the command valid" do expect { test(command, true) }.should_not raise_error end it "should fail if the provider calls the command invalid" do expect { test(command, false) }. should raise_error Puppet::Error, /Parameter #{@param} failed: from a stub/ end end end end shared_examples_for "all exec command parameters that take arrays" do |param| describe "when given an array of inputs" do before :each do @test = Puppet::Type.type(:exec).new(:name => @executable) end it "should accept the array when all commands return valid" do input = %w{one two three} @test.provider.expects(:validatecmd).times(input.length).returns(true) @test[param] = input @test[param].should == input end it "should reject the array when any commands return invalid" do input = %w{one two three} @test.provider.expects(:validatecmd).with(input.first).returns(false) input[1..-1].each do |cmd| @test.provider.expects(:validatecmd).with(cmd).returns(true) end @test[param] = input @test[param].should == input end it "should reject the array when all commands return invalid" do input = %w{one two three} @test.provider.expects(:validatecmd).times(input.length).returns(false) @test[param] = input @test[param].should == input end end end describe "when setting refresh" do it_should_behave_like "all exec command parameters", :refresh end describe "for simple parameters" do before :each do @exec = Puppet::Type.type(:exec).new(:name => @executable) end describe "when setting environment" do { "single values" => "foo=bar", "multiple values" => ["foo=bar", "baz=quux"], }.each do |name, data| it "should accept #{name}" do @exec[:environment] = data @exec[:environment].should == data end end { "single values" => "foo", "only values" => ["foo", "bar"], "any values" => ["foo=bar", "baz"] }.each do |name, data| it "should reject #{name} without assignment" do expect { @exec[:environment] = data }. should raise_error Puppet::Error, /Invalid environment setting/ end end end describe "when setting timeout" do [0, 0.1, 1, 10, 4294967295].each do |valid| it "should accept '#{valid}' as valid" do @exec[:timeout] = valid @exec[:timeout].should == valid end it "should accept '#{valid}' in an array as valid" do @exec[:timeout] = [valid] @exec[:timeout].should == valid end end ['1/2', '', 'foo', '5foo'].each do |invalid| it "should reject '#{invalid}' as invalid" do expect { @exec[:timeout] = invalid }. should raise_error Puppet::Error, /The timeout must be a number/ end it "should reject '#{invalid}' in an array as invalid" do expect { @exec[:timeout] = [invalid] }. should raise_error Puppet::Error, /The timeout must be a number/ end end it "should fail if timeout is exceeded" do ruby_path = Puppet::Util::Execution.ruby_path() ## Leaving this commented version in here because it fails on windows, due to what appears to be ## an assumption about hash iteration order in lib/puppet/type.rb#hash2resource, where ## resource[]= will overwrite the namevar with ":name" if the iteration is in the wrong order #sleep_exec = Puppet::Type.type(:exec).new(:name => 'exec_spec sleep command', :command => "#{ruby_path} -e 'sleep 0.02'", :timeout => '0.01') sleep_exec = Puppet::Type.type(:exec).new(:name => "#{ruby_path} -e 'sleep 0.02'", :timeout => '0.01') lambda { sleep_exec.refresh }.should raise_error Puppet::Error, "Command exceeded timeout" end it "should convert timeout to a float" do command = make_absolute('/bin/false') resource = Puppet::Type.type(:exec).new :command => command, :timeout => "12" resource[:timeout].should be_a(Float) resource[:timeout].should == 12.0 end it "should munge negative timeouts to 0.0" do command = make_absolute('/bin/false') resource = Puppet::Type.type(:exec).new :command => command, :timeout => "-12.0" resource.parameter(:timeout).value.should be_a(Float) resource.parameter(:timeout).value.should == 0.0 end end describe "when setting tries" do [1, 10, 4294967295].each do |valid| it "should accept '#{valid}' as valid" do @exec[:tries] = valid @exec[:tries].should == valid end if "REVISIT: too much test log spam" == "a good thing" then it "should accept '#{valid}' in an array as valid" do pending "inconsistent, but this is not supporting arrays, unlike timeout" @exec[:tries] = [valid] @exec[:tries].should == valid end end end [-3.5, -1, 0, 0.2, '1/2', '1_000_000', '+12', '', 'foo'].each do |invalid| it "should reject '#{invalid}' as invalid" do expect { @exec[:tries] = invalid }. should raise_error Puppet::Error, /Tries must be an integer/ end if "REVISIT: too much test log spam" == "a good thing" then it "should reject '#{invalid}' in an array as invalid" do pending "inconsistent, but this is not supporting arrays, unlike timeout" expect { @exec[:tries] = [invalid] }. should raise_error Puppet::Error, /Tries must be an integer/ end end end end describe "when setting try_sleep" do [0, 0.2, 1, 10, 4294967295].each do |valid| it "should accept '#{valid}' as valid" do @exec[:try_sleep] = valid @exec[:try_sleep].should == valid end if "REVISIT: too much test log spam" == "a good thing" then it "should accept '#{valid}' in an array as valid" do pending "inconsistent, but this is not supporting arrays, unlike timeout" @exec[:try_sleep] = [valid] @exec[:try_sleep].should == valid end end end { -3.5 => "cannot be a negative number", -1 => "cannot be a negative number", '1/2' => 'must be a number', '1_000_000' => 'must be a number', '+12' => 'must be a number', '' => 'must be a number', 'foo' => 'must be a number', }.each do |invalid, error| it "should reject '#{invalid}' as invalid" do expect { @exec[:try_sleep] = invalid }. should raise_error Puppet::Error, /try_sleep #{error}/ end if "REVISIT: too much test log spam" == "a good thing" then it "should reject '#{invalid}' in an array as invalid" do pending "inconsistent, but this is not supporting arrays, unlike timeout" expect { @exec[:try_sleep] = [invalid] }. should raise_error Puppet::Error, /try_sleep #{error}/ end end end end describe "when setting refreshonly" do [:true, :false].each do |value| it "should accept '#{value}'" do @exec[:refreshonly] = value @exec[:refreshonly].should == value end end [1, 0, "1", "0", "yes", "y", "no", "n"].each do |value| it "should reject '#{value}'" do expect { @exec[:refreshonly] = value }. should raise_error(Puppet::Error, /Invalid value #{value.inspect}\. Valid values are true, false/ ) end end end describe "when setting creates" do it_should_behave_like "all path parameters", :creates, :array => true do def instance(path) # Specify shell provider so we don't have to care about command validation Puppet::Type.type(:exec).new(:name => @executable, :creates => path, :provider => :shell) end end end end describe "when setting unless" do it_should_behave_like "all exec command parameters", :unless it_should_behave_like "all exec command parameters that take arrays", :unless end describe "when setting onlyif" do it_should_behave_like "all exec command parameters", :onlyif it_should_behave_like "all exec command parameters that take arrays", :onlyif end describe "#check" do before :each do @test = Puppet::Type.type(:exec).new(:name => @executable) end describe ":refreshonly" do { :true => false, :false => true }.each do |input, result| it "should return '#{result}' when given '#{input}'" do @test[:refreshonly] = input @test.check_all_attributes.should == result end end end describe ":creates" do before :each do @exist = tmpfile('exist') FileUtils.touch(@exist) @unexist = tmpfile('unexist') end context "with a single item" do it "should run when the item does not exist" do @test[:creates] = @unexist @test.check_all_attributes.should == true end it "should not run when the item exists" do @test[:creates] = @exist @test.check_all_attributes.should == false end end context "with an array with one item" do it "should run when the item does not exist" do @test[:creates] = [@unexist] @test.check_all_attributes.should == true end it "should not run when the item exists" do @test[:creates] = [@exist] @test.check_all_attributes.should == false end end context "with an array with multiple items" do it "should run when all items do not exist" do @test[:creates] = [@unexist] * 3 @test.check_all_attributes.should == true end it "should not run when one item exists" do @test[:creates] = [@unexist, @exist, @unexist] @test.check_all_attributes.should == false end it "should not run when all items exist" do @test[:creates] = [@exist] * 3 end end end { :onlyif => { :pass => false, :fail => true }, :unless => { :pass => true, :fail => false }, }.each do |param, sense| describe ":#{param}" do before :each do @pass = make_absolute("/magic/pass") @fail = make_absolute("/magic/fail") @pass_status = stub('status', :exitstatus => sense[:pass] ? 0 : 1) @fail_status = stub('status', :exitstatus => sense[:fail] ? 0 : 1) @test.provider.stubs(:checkexe).returns(true) [true, false].each do |check| @test.provider.stubs(:run).with(@pass, check). returns(['test output', @pass_status]) @test.provider.stubs(:run).with(@fail, check). returns(['test output', @fail_status]) end end context "with a single item" do it "should run if the command exits non-zero" do @test[param] = @fail @test.check_all_attributes.should == true end it "should not run if the command exits zero" do @test[param] = @pass @test.check_all_attributes.should == false end end context "with an array with a single item" do it "should run if the command exits non-zero" do @test[param] = [@fail] @test.check_all_attributes.should == true end it "should not run if the command exits zero" do @test[param] = [@pass] @test.check_all_attributes.should == false end end context "with an array with multiple items" do it "should run if all the commands exits non-zero" do @test[param] = [@fail] * 3 @test.check_all_attributes.should == true end it "should not run if one command exits zero" do @test[param] = [@pass, @fail, @pass] @test.check_all_attributes.should == false end it "should not run if all command exits zero" do @test[param] = [@pass] * 3 @test.check_all_attributes.should == false end end it "should emit output to debug" do Puppet::Util::Log.level = :debug @test[param] = @fail @test.check_all_attributes.should == true @logs.shift.message.should == "test output" end end end end describe "#retrieve" do before :each do @exec_resource = Puppet::Type.type(:exec).new(:name => @bogus_cmd) end it "should return :notrun when check_all_attributes returns true" do @exec_resource.stubs(:check_all_attributes).returns true @exec_resource.retrieve[:returns].should == :notrun end it "should return default exit code 0 when check_all_attributes returns false" do @exec_resource.stubs(:check_all_attributes).returns false @exec_resource.retrieve[:returns].should == ['0'] end it "should return the specified exit code when check_all_attributes returns false" do @exec_resource.stubs(:check_all_attributes).returns false @exec_resource[:returns] = 42 @exec_resource.retrieve[:returns].should == ["42"] end end describe "#output" do before :each do @exec_resource = Puppet::Type.type(:exec).new(:name => @bogus_cmd) end it "should return the provider's run output" do provider = stub 'provider' status = stubs "process_status" status.stubs(:exitstatus).returns("0") provider.expects(:run).returns(["silly output", status]) @exec_resource.stubs(:provider).returns(provider) @exec_resource.refresh @exec_resource.output.should == 'silly output' end end describe "#refresh" do before :each do @exec_resource = Puppet::Type.type(:exec).new(:name => @bogus_cmd) end it "should call provider run with the refresh parameter if it is set" do myother_bogus_cmd = make_absolute('/myother/bogus/cmd') provider = stub 'provider' @exec_resource.stubs(:provider).returns(provider) @exec_resource.stubs(:[]).with(:refresh).returns(myother_bogus_cmd) provider.expects(:run).with(myother_bogus_cmd) @exec_resource.refresh end it "should call provider run with the specified command if the refresh parameter is not set" do provider = stub 'provider' status = stubs "process_status" status.stubs(:exitstatus).returns("0") provider.expects(:run).with(@bogus_cmd).returns(["silly output", status]) @exec_resource.stubs(:provider).returns(provider) @exec_resource.refresh end it "should not run the provider if check_all_attributes is false" do @exec_resource.stubs(:check_all_attributes).returns false provider = stub 'provider' provider.expects(:run).never @exec_resource.stubs(:provider).returns(provider) @exec_resource.refresh end end + + describe "relative and absolute commands vs path" do + let :type do Puppet::Type.type(:exec) end + let :rel do 'echo' end + let :abs do make_absolute('/bin/echo') end + let :path do make_absolute('/bin') end + + it "should fail with relative command and no path" do + expect { type.new(:command => rel) }. + to raise_error Puppet::Error, /no path was specified/ + end + + it "should accept a relative command with a path" do + type.new(:command => rel, :path => path).should be + end + + it "should accept an absolute command with no path" do + type.new(:command => abs).should be + end + + it "should accept an absolute command with a path" do + type.new(:command => abs, :path => path).should be + end + end end diff --git a/spec/unit/type/file_spec.rb b/spec/unit/type/file_spec.rb index 5a2d07e69..97b49c37b 100755 --- a/spec/unit/type/file_spec.rb +++ b/spec/unit/type/file_spec.rb @@ -1,1522 +1,1522 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Type.type(:file) do include PuppetSpec::Files let(:path) { tmpfile('file_testing') } let(:file) { described_class.new(:path => path, :catalog => catalog) } let(:provider) { file.provider } let(:catalog) { Puppet::Resource::Catalog.new } before do @real_posix = Puppet.features.posix? Puppet.features.stubs("posix?").returns(true) end describe "the path parameter" do describe "on POSIX systems", :if => Puppet.features.posix? do it "should remove trailing slashes" do file[:path] = "/foo/bar/baz/" file[:path].should == "/foo/bar/baz" end it "should remove double slashes" do file[:path] = "/foo/bar//baz" file[:path].should == "/foo/bar/baz" end it "should remove trailing double slashes" do file[:path] = "/foo/bar/baz//" file[:path].should == "/foo/bar/baz" end it "should leave a single slash alone" do file[:path] = "/" file[:path].should == "/" end it "should accept a double-slash at the start of the path" do expect { file[:path] = "//tmp/xxx" # REVISIT: This should be wrong, later. See the next test. # --daniel 2011-01-31 file[:path].should == '/tmp/xxx' }.should_not raise_error end # REVISIT: This is pending, because I don't want to try and audit the # entire codebase to make sure we get this right. POSIX treats two (and # exactly two) '/' characters at the start of the path specially. # # See sections 3.2 and 4.11, which allow DomainOS to be all special like # and still have the POSIX branding and all. --daniel 2011-01-31 it "should preserve the double-slash at the start of the path" end describe "on Windows systems", :if => Puppet.features.microsoft_windows? do it "should remove trailing slashes" do file[:path] = "X:/foo/bar/baz/" file[:path].should == "X:/foo/bar/baz" end it "should remove double slashes" do file[:path] = "X:/foo/bar//baz" file[:path].should == "X:/foo/bar/baz" end it "should remove trailing double slashes" do file[:path] = "X:/foo/bar/baz//" file[:path].should == "X:/foo/bar/baz" end - it "should leave a drive letter with a slash alone", :'fails_on_ruby_1.9.2' => true do + it "should leave a drive letter with a slash alone" do file[:path] = "X:/" file[:path].should == "X:/" end - it "should not accept a drive letter without a slash", :'fails_on_ruby_1.9.2' => true do + it "should not accept a drive letter without a slash" do lambda { file[:path] = "X:" }.should raise_error(/File paths must be fully qualified/) end - describe "when using UNC filenames", :if => Puppet.features.microsoft_windows?, :'fails_on_ruby_1.9.2' => true do + describe "when using UNC filenames", :if => Puppet.features.microsoft_windows? do before :each do pending("UNC file paths not yet supported") end it "should remove trailing slashes" do file[:path] = "//server/foo/bar/baz/" file[:path].should == "//server/foo/bar/baz" end it "should remove double slashes" do file[:path] = "//server/foo/bar//baz" file[:path].should == "//server/foo/bar/baz" end it "should remove trailing double slashes" do file[:path] = "//server/foo/bar/baz//" file[:path].should == "//server/foo/bar/baz" end it "should remove a trailing slash from a sharename" do file[:path] = "//server/foo/" file[:path].should == "//server/foo" end it "should not modify a sharename" do file[:path] = "//server/foo" file[:path].should == "//server/foo" end end end end describe "the backup parameter" do [false, 'false', :false].each do |value| it "should disable backup if the value is #{value.inspect}" do file[:backup] = value file[:backup].should == false end end [true, 'true', '.puppet-bak'].each do |value| it "should use .puppet-bak if the value is #{value.inspect}" do file[:backup] = value file[:backup].should == '.puppet-bak' end end it "should use the provided value if it's any other string" do file[:backup] = "over there" file[:backup].should == "over there" end it "should fail if backup is set to anything else" do expect do file[:backup] = 97 end.to raise_error(Puppet::Error, /Invalid backup type 97/) end end describe "the recurse parameter" do it "should default to recursion being disabled" do file[:recurse].should be_false end [true, "true", 10, "inf", "remote"].each do |value| it "should consider #{value} to enable recursion" do file[:recurse] = value file[:recurse].should be_true end end [false, "false", 0].each do |value| it "should consider #{value} to disable recursion" do file[:recurse] = value file[:recurse].should be_false end end it "should warn if recurse is specified as a number" do Puppet.expects(:deprecation_warning).with("Setting recursion depth with the recurse parameter is now deprecated, please use recurselimit") file[:recurse] = 3 end end describe "the recurselimit parameter" do it "should accept integers" do file[:recurselimit] = 12 file[:recurselimit].should == 12 end it "should munge string numbers to number numbers" do file[:recurselimit] = '12' file[:recurselimit].should == 12 end it "should fail if given a non-number" do expect do file[:recurselimit] = 'twelve' end.to raise_error(Puppet::Error, /Invalid value "twelve"/) end end describe "the replace parameter" do [true, :true, :yes].each do |value| it "should consider #{value} to be true" do file[:replace] = value file[:replace].should == :true end end [false, :false, :no].each do |value| it "should consider #{value} to be false" do file[:replace] = value file[:replace].should == :false end end end describe "#[]" do it "should raise an exception" do expect do described_class['anything'] end.to raise_error("Global resource access is deprecated") end end describe ".instances" do it "should return an empty array" do described_class.instances.should == [] end end describe "#asuser" do before :each do # Mocha won't let me just stub SUIDManager.asuser to yield and return, # but it will do exactly that if we're not root. Puppet.features.stubs(:root?).returns false end it "should return the desired owner if they can write to the parent directory" do file[:owner] = 1001 FileTest.stubs(:writable?).with(File.dirname file[:path]).returns true file.asuser.should == 1001 end it "should return nil if the desired owner can't write to the parent directory" do file[:owner] = 1001 FileTest.stubs(:writable?).with(File.dirname file[:path]).returns false file.asuser.should == nil end it "should return nil if not managing owner" do file.asuser.should == nil end end describe "#bucket" do it "should return nil if backup is off" do file[:backup] = false file.bucket.should == nil end it "should not return a bucket if using a file extension for backup" do file[:backup] = '.backup' file.bucket.should == nil end it "should return the default filebucket if using the 'puppet' filebucket" do file[:backup] = 'puppet' bucket = stub('bucket') file.stubs(:default_bucket).returns bucket file.bucket.should == bucket end it "should fail if using a remote filebucket and no catalog exists" do file.catalog = nil file[:backup] = 'my_bucket' expect { file.bucket }.to raise_error(Puppet::Error, "Can not find filebucket for backups without a catalog") end it "should fail if the specified filebucket isn't in the catalog" do file[:backup] = 'my_bucket' expect { file.bucket }.to raise_error(Puppet::Error, "Could not find filebucket my_bucket specified in backup") end it "should use the specified filebucket if it is in the catalog" do file[:backup] = 'my_bucket' filebucket = Puppet::Type.type(:filebucket).new(:name => 'my_bucket') catalog.add_resource(filebucket) file.bucket.should == filebucket.bucket end end describe "#asuser" do before :each do # Mocha won't let me just stub SUIDManager.asuser to yield and return, # but it will do exactly that if we're not root. Puppet.features.stubs(:root?).returns false end it "should return the desired owner if they can write to the parent directory" do file[:owner] = 1001 FileTest.stubs(:writable?).with(File.dirname file[:path]).returns true file.asuser.should == 1001 end it "should return nil if the desired owner can't write to the parent directory" do file[:owner] = 1001 FileTest.stubs(:writable?).with(File.dirname file[:path]).returns false file.asuser.should == nil end it "should return nil if not managing owner" do file.asuser.should == nil end end describe "#bucket" do it "should return nil if backup is off" do file[:backup] = false file.bucket.should == nil end it "should return nil if using a file extension for backup" do file[:backup] = '.backup' file.bucket.should == nil end it "should return the default filebucket if using the 'puppet' filebucket" do file[:backup] = 'puppet' bucket = stub('bucket') file.stubs(:default_bucket).returns bucket file.bucket.should == bucket end it "should fail if using a remote filebucket and no catalog exists" do file.catalog = nil file[:backup] = 'my_bucket' expect { file.bucket }.to raise_error(Puppet::Error, "Can not find filebucket for backups without a catalog") end it "should fail if the specified filebucket isn't in the catalog" do file[:backup] = 'my_bucket' expect { file.bucket }.to raise_error(Puppet::Error, "Could not find filebucket my_bucket specified in backup") end it "should use the specified filebucket if it is in the catalog" do file[:backup] = 'my_bucket' filebucket = Puppet::Type.type(:filebucket).new(:name => 'my_bucket') catalog.add_resource(filebucket) file.bucket.should == filebucket.bucket end end describe "#exist?" do it "should be considered existent if it can be stat'ed" do file.expects(:stat).returns mock('stat') file.must be_exist end it "should be considered nonexistent if it can not be stat'ed" do file.expects(:stat).returns nil file.must_not be_exist end end describe "#eval_generate" do before do @graph = stub 'graph', :add_edge => nil catalog.stubs(:relationship_graph).returns @graph end it "should recurse if recursion is enabled" do resource = stub('resource', :[] => 'resource') file.expects(:recurse).returns [resource] file[:recurse] = true file.eval_generate.should == [resource] end it "should not recurse if recursion is disabled" do file.expects(:recurse).never file[:recurse] = false file.eval_generate.should == [] end end describe "#ancestors" do it "should return the ancestors of the file, in ascending order" do file = described_class.new(:path => make_absolute("/tmp/foo/bar/baz/qux")) pieces = %W[#{make_absolute('/')} tmp foo bar baz] ancestors = file.ancestors ancestors.should_not be_empty ancestors.reverse.each_with_index do |path,i| path.should == File.join(*pieces[0..i]) end end end describe "#flush" do it "should flush all properties that respond to :flush" do file[:source] = File.expand_path(__FILE__) file.parameter(:source).expects(:flush) file.flush end it "should reset its stat reference" do FileUtils.touch(path) stat1 = file.stat file.stat.should equal(stat1) file.flush file.stat.should_not equal(stat1) end end describe "#initialize" do it "should remove a trailing slash from the title to create the path" do title = File.expand_path("/abc/\n\tdef/") file = described_class.new(:title => title) file[:path].should == title end it "should set a desired 'ensure' value if none is set and 'content' is set" do file = described_class.new(:path => path, :content => "/foo/bar") file[:ensure].should == :file end it "should set a desired 'ensure' value if none is set and 'target' is set" do file = described_class.new(:path => path, :target => File.expand_path(__FILE__)) file[:ensure].should == :symlink end end describe "#mark_children_for_purging" do it "should set each child's ensure to absent" do paths = %w[foo bar baz] children = paths.inject({}) do |children,child| children.merge child => described_class.new(:path => File.join(path, child), :ensure => :present) end file.mark_children_for_purging(children) children.length.should == 3 children.values.each do |child| child[:ensure].should == :absent end end it "should skip children which have a source" do child = described_class.new(:path => path, :ensure => :present, :source => File.expand_path(__FILE__)) file.mark_children_for_purging('foo' => child) child[:ensure].should == :present end end describe "#newchild" do it "should create a new resource relative to the parent" do child = file.newchild('bar') child.should be_a(described_class) child[:path].should == File.join(file[:path], 'bar') end { :ensure => :present, :recurse => true, :recurselimit => 5, :target => "some_target", :source => File.expand_path("some_source"), }.each do |param, value| it "should omit the #{param} parameter" do # Make a new file, because we have to set the param at initialization # or it wouldn't be copied regardless. file = described_class.new(:path => path, param => value) child = file.newchild('bar') child[param].should_not == value end end it "should copy all of the parent resource's 'should' values that were set at initialization" do parent = described_class.new(:path => path, :owner => 'root', :group => 'wheel') child = parent.newchild("my/path") child[:owner].should == 'root' child[:group].should == 'wheel' end it "should not copy default values to the new child" do child = file.newchild("my/path") child.original_parameters.should_not include(:backup) end it "should not copy values to the child which were set by the source" do source = File.expand_path(__FILE__) file[:source] = source metadata = stub 'metadata', :owner => "root", :group => "root", :mode => 0755, :ftype => "file", :checksum => "{md5}whatever", :source => source file.parameter(:source).stubs(:metadata).returns metadata file.parameter(:source).copy_source_values file.class.expects(:new).with { |params| params[:group].nil? } file.newchild("my/path") end end describe "#purge?" do it "should return false if purge is not set" do file.must_not be_purge end it "should return true if purge is set to true" do file[:purge] = true file.must be_purge end it "should return false if purge is set to false" do file[:purge] = false file.must_not be_purge end end describe "#recurse" do before do file[:recurse] = true @metadata = Puppet::FileServing::Metadata end describe "and a source is set" do it "should pass the already-discovered resources to recurse_remote" do file[:source] = File.expand_path(__FILE__) file.stubs(:recurse_local).returns(:foo => "bar") file.expects(:recurse_remote).with(:foo => "bar").returns [] file.recurse end end describe "and a target is set" do it "should use recurse_link" do file[:target] = File.expand_path(__FILE__) file.stubs(:recurse_local).returns(:foo => "bar") file.expects(:recurse_link).with(:foo => "bar").returns [] file.recurse end end it "should use recurse_local if recurse is not remote" do file.expects(:recurse_local).returns({}) file.recurse end it "should not use recurse_local if recurse is remote" do file[:recurse] = :remote file.expects(:recurse_local).never file.recurse end it "should return the generated resources as an array sorted by file path" do one = stub 'one', :[] => "/one" two = stub 'two', :[] => "/one/two" three = stub 'three', :[] => "/three" file.expects(:recurse_local).returns(:one => one, :two => two, :three => three) file.recurse.should == [one, two, three] end describe "and purging is enabled" do before do file[:purge] = true end it "should mark each file for removal" do local = described_class.new(:path => path, :ensure => :present) file.expects(:recurse_local).returns("local" => local) file.recurse local[:ensure].should == :absent end it "should not remove files that exist in the remote repository" do file[:source] = File.expand_path(__FILE__) file.expects(:recurse_local).returns({}) remote = described_class.new(:path => path, :source => File.expand_path(__FILE__), :ensure => :present) file.expects(:recurse_remote).with { |hash| hash["remote"] = remote } file.recurse remote[:ensure].should_not == :absent end end end describe "#remove_less_specific_files" do it "should remove any nested files that are already in the catalog" do foo = described_class.new :path => File.join(file[:path], 'foo') bar = described_class.new :path => File.join(file[:path], 'bar') baz = described_class.new :path => File.join(file[:path], 'baz') catalog.add_resource(foo) catalog.add_resource(bar) file.remove_less_specific_files([foo, bar, baz]).should == [baz] end end describe "#remove_less_specific_files" do it "should remove any nested files that are already in the catalog" do foo = described_class.new :path => File.join(file[:path], 'foo') bar = described_class.new :path => File.join(file[:path], 'bar') baz = described_class.new :path => File.join(file[:path], 'baz') catalog.add_resource(foo) catalog.add_resource(bar) file.remove_less_specific_files([foo, bar, baz]).should == [baz] end end describe "#recurse?" do it "should be true if recurse is true" do file[:recurse] = true file.must be_recurse end it "should be true if recurse is remote" do file[:recurse] = :remote file.must be_recurse end it "should be false if recurse is false" do file[:recurse] = false file.must_not be_recurse end end describe "#recurse_link" do before do @first = stub 'first', :relative_path => "first", :full_path => "/my/first", :ftype => "directory" @second = stub 'second', :relative_path => "second", :full_path => "/my/second", :ftype => "file" @resource = stub 'file', :[]= => nil end it "should pass its target to the :perform_recursion method" do file[:target] = "mylinks" file.expects(:perform_recursion).with("mylinks").returns [@first] file.stubs(:newchild).returns @resource file.recurse_link({}) end it "should ignore the recursively-found '.' file and configure the top-level file to create a directory" do @first.stubs(:relative_path).returns "." file[:target] = "mylinks" file.expects(:perform_recursion).with("mylinks").returns [@first] file.stubs(:newchild).never file.expects(:[]=).with(:ensure, :directory) file.recurse_link({}) end it "should create a new child resource for each generated metadata instance's relative path that doesn't already exist in the children hash" do file.expects(:perform_recursion).returns [@first, @second] file.expects(:newchild).with(@first.relative_path).returns @resource file.recurse_link("second" => @resource) end it "should not create a new child resource for paths that already exist in the children hash" do file.expects(:perform_recursion).returns [@first] file.expects(:newchild).never file.recurse_link("first" => @resource) end it "should set the target to the full path of discovered file and set :ensure to :link if the file is not a directory" do file.stubs(:perform_recursion).returns [@first, @second] file.recurse_link("first" => @resource, "second" => file) file[:ensure].should == :link file[:target].should == "/my/second" end it "should :ensure to :directory if the file is a directory" do file.stubs(:perform_recursion).returns [@first, @second] file.recurse_link("first" => file, "second" => @resource) file[:ensure].should == :directory end it "should return a hash with both created and existing resources with the relative paths as the hash keys" do file.expects(:perform_recursion).returns [@first, @second] file.stubs(:newchild).returns file file.recurse_link("second" => @resource).should == {"second" => @resource, "first" => file} end end describe "#recurse_local" do before do @metadata = stub 'metadata', :relative_path => "my/file" end it "should pass its path to the :perform_recursion method" do file.expects(:perform_recursion).with(file[:path]).returns [@metadata] file.stubs(:newchild) file.recurse_local end it "should return an empty hash if the recursion returns nothing" do file.expects(:perform_recursion).returns nil file.recurse_local.should == {} end it "should create a new child resource with each generated metadata instance's relative path" do file.expects(:perform_recursion).returns [@metadata] file.expects(:newchild).with(@metadata.relative_path).returns "fiebar" file.recurse_local end it "should not create a new child resource for the '.' directory" do @metadata.stubs(:relative_path).returns "." file.expects(:perform_recursion).returns [@metadata] file.expects(:newchild).never file.recurse_local end it "should return a hash of the created resources with the relative paths as the hash keys" do file.expects(:perform_recursion).returns [@metadata] file.expects(:newchild).with("my/file").returns "fiebar" file.recurse_local.should == {"my/file" => "fiebar"} end it "should set checksum_type to none if this file checksum is none" do file[:checksum] = :none Puppet::FileServing::Metadata.indirection.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata] file.expects(:newchild).with("my/file").returns "fiebar" file.recurse_local end end describe "#recurse_remote" do let(:my) { File.expand_path('/my') } before do file[:source] = "puppet://foo/bar" @first = Puppet::FileServing::Metadata.new(my, :relative_path => "first") @second = Puppet::FileServing::Metadata.new(my, :relative_path => "second") @first.stubs(:ftype).returns "directory" @second.stubs(:ftype).returns "directory" @parameter = stub 'property', :metadata= => nil @resource = stub 'file', :[]= => nil, :parameter => @parameter end it "should pass its source to the :perform_recursion method" do data = Puppet::FileServing::Metadata.new(File.expand_path("/whatever"), :relative_path => "foobar") file.expects(:perform_recursion).with("puppet://foo/bar").returns [data] file.stubs(:newchild).returns @resource file.recurse_remote({}) end it "should not recurse when the remote file is not a directory" do data = Puppet::FileServing::Metadata.new(File.expand_path("/whatever"), :relative_path => ".") data.stubs(:ftype).returns "file" file.expects(:perform_recursion).with("puppet://foo/bar").returns [data] file.expects(:newchild).never file.recurse_remote({}) end it "should set the source of each returned file to the searched-for URI plus the found relative path" do @first.expects(:source=).with File.join("puppet://foo/bar", @first.relative_path) file.expects(:perform_recursion).returns [@first] file.stubs(:newchild).returns @resource file.recurse_remote({}) end it "should create a new resource for any relative file paths that do not already have a resource" do file.stubs(:perform_recursion).returns [@first] file.expects(:newchild).with("first").returns @resource file.recurse_remote({}).should == {"first" => @resource} end it "should not create a new resource for any relative file paths that do already have a resource" do file.stubs(:perform_recursion).returns [@first] file.expects(:newchild).never file.recurse_remote("first" => @resource) end it "should set the source of each resource to the source of the metadata" do file.stubs(:perform_recursion).returns [@first] @resource.stubs(:[]=) @resource.expects(:[]=).with(:source, File.join("puppet://foo/bar", @first.relative_path)) file.recurse_remote("first" => @resource) end # LAK:FIXME This is a bug, but I can't think of a fix for it. Fortunately it's already # filed, and when it's fixed, we'll just fix the whole flow. it "should set the checksum type to :md5 if the remote file is a file" do @first.stubs(:ftype).returns "file" file.stubs(:perform_recursion).returns [@first] @resource.stubs(:[]=) @resource.expects(:[]=).with(:checksum, :md5) file.recurse_remote("first" => @resource) end it "should store the metadata in the source property for each resource so the source does not have to requery the metadata" do file.stubs(:perform_recursion).returns [@first] @resource.expects(:parameter).with(:source).returns @parameter @parameter.expects(:metadata=).with(@first) file.recurse_remote("first" => @resource) end it "should not create a new resource for the '.' file" do @first.stubs(:relative_path).returns "." file.stubs(:perform_recursion).returns [@first] file.expects(:newchild).never file.recurse_remote({}) end it "should store the metadata in the main file's source property if the relative path is '.'" do @first.stubs(:relative_path).returns "." file.stubs(:perform_recursion).returns [@first] file.parameter(:source).expects(:metadata=).with @first file.recurse_remote("first" => @resource) end describe "and multiple sources are provided" do let(:sources) do h = {} %w{/a /b /c /d}.each do |key| h[key] = URI.unescape(Puppet::Util.path_to_uri(File.expand_path(key)).to_s) end h end describe "and :sourceselect is set to :first" do it "should create file instances for the results for the first source to return any values" do data = Puppet::FileServing::Metadata.new(File.expand_path("/whatever"), :relative_path => "foobar") file[:source] = sources.keys.sort.map { |key| File.expand_path(key) } file.expects(:perform_recursion).with(sources['/a']).returns nil file.expects(:perform_recursion).with(sources['/b']).returns [] file.expects(:perform_recursion).with(sources['/c']).returns [data] file.expects(:perform_recursion).with(sources['/d']).never file.expects(:newchild).with("foobar").returns @resource file.recurse_remote({}) end end describe "and :sourceselect is set to :all" do before do file[:sourceselect] = :all end it "should return every found file that is not in a previous source" do klass = Puppet::FileServing::Metadata file[:source] = abs_path = %w{/a /b /c /d}.map {|f| File.expand_path(f) } file.stubs(:newchild).returns @resource one = [klass.new(abs_path[0], :relative_path => "a")] file.expects(:perform_recursion).with(sources['/a']).returns one file.expects(:newchild).with("a").returns @resource two = [klass.new(abs_path[1], :relative_path => "a"), klass.new(abs_path[1], :relative_path => "b")] file.expects(:perform_recursion).with(sources['/b']).returns two file.expects(:newchild).with("b").returns @resource three = [klass.new(abs_path[2], :relative_path => "a"), klass.new(abs_path[2], :relative_path => "c")] file.expects(:perform_recursion).with(sources['/c']).returns three file.expects(:newchild).with("c").returns @resource file.expects(:perform_recursion).with(sources['/d']).returns [] file.recurse_remote({}) end end end end describe "#perform_recursion" do it "should use Metadata to do its recursion" do Puppet::FileServing::Metadata.indirection.expects(:search) file.perform_recursion(file[:path]) end it "should use the provided path as the key to the search" do Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| key == "/foo" } file.perform_recursion("/foo") end it "should return the results of the metadata search" do Puppet::FileServing::Metadata.indirection.expects(:search).returns "foobar" file.perform_recursion(file[:path]).should == "foobar" end it "should pass its recursion value to the search" do file[:recurse] = true Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true } file.perform_recursion(file[:path]) end it "should pass true if recursion is remote" do file[:recurse] = :remote Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true } file.perform_recursion(file[:path]) end it "should pass its recursion limit value to the search" do file[:recurselimit] = 10 Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurselimit] == 10 } file.perform_recursion(file[:path]) end it "should configure the search to ignore or manage links" do file[:links] = :manage Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:links] == :manage } file.perform_recursion(file[:path]) end it "should pass its 'ignore' setting to the search if it has one" do file[:ignore] = %w{.svn CVS} Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} } file.perform_recursion(file[:path]) end end describe "#remove_existing" do it "should do nothing if the file doesn't exist" do file.remove_existing(:file).should == nil end it "should fail if it can't backup the file" do file.stubs(:stat).returns stub('stat') file.stubs(:perform_backup).returns false expect { file.remove_existing(:file) }.to raise_error(Puppet::Error, /Could not back up; will not replace/) end it "should not do anything if the file is already the right type and not a link" do file.stubs(:stat).returns stub('stat', :ftype => 'file') file.remove_existing(:file).should == nil end it "should not remove directories and should not invalidate the stat unless force is set" do # Actually call stat to set @needs_stat to nil file.stat file.stubs(:stat).returns stub('stat', :ftype => 'directory') file.remove_existing(:file) file.instance_variable_get(:@stat).should == nil @logs.should be_any {|log| log.level == :notice and log.message =~ /Not removing directory; use 'force' to override/} end it "should remove a directory if force is set" do file[:force] = true file.stubs(:stat).returns stub('stat', :ftype => 'directory') FileUtils.expects(:rmtree).with(file[:path]) file.remove_existing(:file).should == true end it "should remove an existing file" do file.stubs(:perform_backup).returns true FileUtils.touch(path) file.remove_existing(:directory).should == true File.exists?(file[:path]).should == false end it "should remove an existing link", :unless => Puppet.features.microsoft_windows? do file.stubs(:perform_backup).returns true target = tmpfile('link_target') FileUtils.touch(target) FileUtils.symlink(target, path) file[:target] = target file.remove_existing(:directory).should == true File.exists?(file[:path]).should == false end it "should fail if the file is not a file, link, or directory" do file.stubs(:stat).returns stub('stat', :ftype => 'socket') expect { file.remove_existing(:file) }.to raise_error(Puppet::Error, /Could not back up files of type socket/) end it "should invalidate the existing stat of the file" do # Actually call stat to set @needs_stat to nil file.stat file.stubs(:stat).returns stub('stat', :ftype => 'file') File.stubs(:unlink) file.remove_existing(:directory).should == true file.instance_variable_get(:@stat).should == :needs_stat end end describe "#retrieve" do it "should copy the source values if the 'source' parameter is set" do file[:source] = File.expand_path('/foo/bar') file.parameter(:source).expects(:copy_source_values) file.retrieve end end describe "#should_be_file?" do it "should have a method for determining if the file should be a normal file" do file.must respond_to(:should_be_file?) end it "should be a file if :ensure is set to :file" do file[:ensure] = :file file.must be_should_be_file end it "should be a file if :ensure is set to :present and the file exists as a normal file" do file.stubs(:stat).returns(mock('stat', :ftype => "file")) file[:ensure] = :present file.must be_should_be_file end it "should not be a file if :ensure is set to something other than :file" do file[:ensure] = :directory file.must_not be_should_be_file end it "should not be a file if :ensure is set to :present and the file exists but is not a normal file" do file.stubs(:stat).returns(mock('stat', :ftype => "directory")) file[:ensure] = :present file.must_not be_should_be_file end it "should be a file if :ensure is not set and :content is" do file[:content] = "foo" file.must be_should_be_file end it "should be a file if neither :ensure nor :content is set but the file exists as a normal file" do file.stubs(:stat).returns(mock("stat", :ftype => "file")) file.must be_should_be_file end it "should not be a file if neither :ensure nor :content is set but the file exists but not as a normal file" do file.stubs(:stat).returns(mock("stat", :ftype => "directory")) file.must_not be_should_be_file end end describe "#stat", :unless => Puppet.features.microsoft_windows? do before do target = tmpfile('link_target') FileUtils.touch(target) FileUtils.symlink(target, path) file[:target] = target file[:links] = :manage # so we always use :lstat end it "should stat the target if it is following links" do file[:links] = :follow file.stat.ftype.should == 'file' end it "should stat the link if is it not following links" do file[:links] = :manage file.stat.ftype.should == 'link' end it "should return nil if the file does not exist" do file[:path] = '/foo/bar/baz/non-existent' file.stat.should be_nil end it "should return nil if the file cannot be stat'ed" do dir = tmpfile('link_test_dir') child = File.join(dir, 'some_file') Dir.mkdir(dir) File.chmod(0, dir) file[:path] = child file.stat.should be_nil # chmod it back so we can clean it up File.chmod(0777, dir) end it "should return the stat instance" do file.stat.should be_a(File::Stat) end it "should cache the stat instance" do file.stat.should equal(file.stat) end end describe "#write" do it "should propagate failures encountered when renaming the temporary file" do File.stubs(:open) File.expects(:rename).raises ArgumentError file[:backup] = 'puppet' file.stubs(:validate_checksum?).returns(false) property = stub('content_property', :actual_content => "something", :length => "something".length) file.stubs(:property).with(:content).returns(property) lambda { file.write(:content) }.should raise_error(Puppet::Error) end it "should delegate writing to the content property" do filehandle = stub_everything 'fh' File.stubs(:open).yields(filehandle) File.stubs(:rename) property = stub('content_property', :actual_content => "something", :length => "something".length) file[:backup] = 'puppet' file.stubs(:validate_checksum?).returns(false) file.stubs(:property).with(:content).returns(property) property.expects(:write).with(filehandle) file.write(:content) end describe "when validating the checksum" do before { file.stubs(:validate_checksum?).returns(true) } it "should fail if the checksum parameter and content checksums do not match" do checksum = stub('checksum_parameter', :sum => 'checksum_b', :sum_file => 'checksum_b') file.stubs(:parameter).with(:checksum).returns(checksum) property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a') file.stubs(:property).with(:content).returns(property) lambda { file.write :NOTUSED }.should raise_error(Puppet::Error) end end describe "when not validating the checksum" do before { file.stubs(:validate_checksum?).returns(false) } it "should not fail if the checksum property and content checksums do not match" do checksum = stub('checksum_parameter', :sum => 'checksum_b') file.stubs(:parameter).with(:checksum).returns(checksum) property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a') file.stubs(:property).with(:content).returns(property) lambda { file.write :NOTUSED }.should_not raise_error(Puppet::Error) end end end describe "#fail_if_checksum_is_wrong" do it "should fail if the checksum of the file doesn't match the expected one" do expect do file.instance_eval do parameter(:checksum).stubs(:sum_file).returns('wrong!!') fail_if_checksum_is_wrong(self[:path], 'anything!') end end.to raise_error(Puppet::Error, /File written to disk did not match checksum/) end it "should not fail if the checksum is correct" do file.instance_eval do parameter(:checksum).stubs(:sum_file).returns('anything!') fail_if_checksum_is_wrong(self[:path], 'anything!').should == nil end end it "should not fail if the checksum is absent" do file.instance_eval do parameter(:checksum).stubs(:sum_file).returns(nil) fail_if_checksum_is_wrong(self[:path], 'anything!').should == nil end end end describe "#write_content" do it "should delegate writing the file to the content property" do io = stub('io') file[:content] = "some content here" file.property(:content).expects(:write).with(io) file.send(:write_content, io) end end describe "#write_temporary_file?" do it "should be true if the file has specified content" do file[:content] = 'some content' file.send(:write_temporary_file?).should be_true end it "should be true if the file has specified source" do file[:source] = File.expand_path('/tmp/foo') file.send(:write_temporary_file?).should be_true end it "should be false if the file has neither content nor source" do file.send(:write_temporary_file?).should be_false end end describe "#property_fix" do { :mode => 0777, :owner => 'joeuser', :group => 'joeusers', :seluser => 'seluser', :selrole => 'selrole', :seltype => 'seltype', :selrange => 'selrange' }.each do |name,value| it "should sync the #{name} property if it's not in sync" do file[name] = value prop = file.property(name) prop.expects(:retrieve) prop.expects(:safe_insync?).returns false prop.expects(:sync) file.send(:property_fix) end end end describe "when autorequiring" do describe "target" do it "should require file resource when specified with the target property" do file = described_class.new(:path => File.expand_path("/foo"), :ensure => :directory) link = described_class.new(:path => File.expand_path("/bar"), :ensure => :symlink, :target => File.expand_path("/foo")) catalog.add_resource file catalog.add_resource link reqs = link.autorequire reqs.size.must == 1 reqs[0].source.must == file reqs[0].target.must == link end it "should require file resource when specified with the ensure property" do file = described_class.new(:path => File.expand_path("/foo"), :ensure => :directory) link = described_class.new(:path => File.expand_path("/bar"), :ensure => File.expand_path("/foo")) catalog.add_resource file catalog.add_resource link reqs = link.autorequire reqs.size.must == 1 reqs[0].source.must == file reqs[0].target.must == link end it "should not require target if target is not managed" do link = described_class.new(:path => File.expand_path('/foo'), :ensure => :symlink, :target => '/bar') catalog.add_resource link link.autorequire.size.should == 0 end end describe "directories" do it "should autorequire its parent directory" do dir = described_class.new(:path => File.dirname(path)) catalog.add_resource file catalog.add_resource dir reqs = file.autorequire reqs[0].source.must == dir reqs[0].target.must == file end it "should autorequire its nearest ancestor directory" do dir = described_class.new(:path => File.dirname(path)) grandparent = described_class.new(:path => File.dirname(File.dirname(path))) catalog.add_resource file catalog.add_resource dir catalog.add_resource grandparent reqs = file.autorequire reqs.length.must == 1 reqs[0].source.must == dir reqs[0].target.must == file end it "should not autorequire anything when there is no nearest ancestor directory" do catalog.add_resource file file.autorequire.should be_empty end it "should not autorequire its parent dir if its parent dir is itself" do file[:path] = File.expand_path('/') catalog.add_resource file file.autorequire.should be_empty end describe "on Windows systems", :if => Puppet.features.microsoft_windows? do describe "when using UNC filenames" do it "should autorequire its parent directory" do file[:path] = '//server/foo/bar/baz' dir = described_class.new(:path => "//server/foo/bar") catalog.add_resource file catalog.add_resource dir reqs = file.autorequire reqs[0].source.must == dir reqs[0].target.must == file end it "should autorequire its nearest ancestor directory" do file = described_class.new(:path => "//server/foo/bar/baz/qux") dir = described_class.new(:path => "//server/foo/bar/baz") grandparent = described_class.new(:path => "//server/foo/bar") catalog.add_resource file catalog.add_resource dir catalog.add_resource grandparent reqs = file.autorequire reqs.length.must == 1 reqs[0].source.must == dir reqs[0].target.must == file end it "should not autorequire anything when there is no nearest ancestor directory" do file = described_class.new(:path => "//server/foo/bar/baz/qux") catalog.add_resource file file.autorequire.should be_empty end it "should not autorequire its parent dir if its parent dir is itself" do file = described_class.new(:path => "//server/foo") catalog.add_resource file puts file.autorequire file.autorequire.should be_empty end end end end end describe "when managing links" do require 'tempfile' if @real_posix describe "on POSIX systems" do before do Dir.mkdir(path) @target = File.join(path, "target") @link = File.join(path, "link") File.open(@target, "w", 0644) { |f| f.puts "yayness" } File.symlink(@target, @link) file[:path] = @link file[:mode] = 0755 catalog.add_resource file end it "should default to managing the link" do catalog.apply # I convert them to strings so they display correctly if there's an error. (File.stat(@target).mode & 007777).to_s(8).should == '644' end it "should be able to follow links" do file[:links] = :follow catalog.apply (File.stat(@target).mode & 007777).to_s(8).should == '755' end end else # @real_posix # should recode tests using expectations instead of using the filesystem end describe "on Microsoft Windows systems" do before do Puppet.features.stubs(:posix?).returns(false) Puppet.features.stubs(:microsoft_windows?).returns(true) end it "should refuse to work with links" end end describe "when using source" do before do file[:source] = File.expand_path('/one') end Puppet::Type::File::ParameterChecksum.value_collection.values.reject {|v| v == :none}.each do |checksum_type| describe "with checksum '#{checksum_type}'" do before do file[:checksum] = checksum_type end it 'should validate' do lambda { file.validate }.should_not raise_error end end end describe "with checksum 'none'" do before do file[:checksum] = :none end it 'should raise an exception when validating' do lambda { file.validate }.should raise_error(/You cannot specify source when using checksum 'none'/) end end end describe "when using content" do before do file[:content] = 'file contents' end (Puppet::Type::File::ParameterChecksum.value_collection.values - SOURCE_ONLY_CHECKSUMS).each do |checksum_type| describe "with checksum '#{checksum_type}'" do before do file[:checksum] = checksum_type end it 'should validate' do lambda { file.validate }.should_not raise_error end end end SOURCE_ONLY_CHECKSUMS.each do |checksum_type| describe "with checksum '#{checksum_type}'" do it 'should raise an exception when validating' do file[:checksum] = checksum_type lambda { file.validate }.should raise_error(/You cannot specify content when using checksum '#{checksum_type}'/) end end end end describe "when auditing" do before :each do # to prevent the catalog from trying to write state.yaml Puppet::Util::Storage.stubs(:store) end it "should not fail if creating a new file if group is not set" do file = described_class.new(:path => path, :audit => 'all', :content => 'content') catalog.add_resource(file) report = catalog.apply.report report.resource_statuses["File[#{path}]"].should_not be_failed File.read(path).should == 'content' end it "should not log errors if creating a new file with ensure present and no content" do file[:audit] = 'content' file[:ensure] = 'present' catalog.add_resource(file) catalog.apply File.should be_exist(path) @logs.should_not be_any {|l| l.level != :notice } end end describe "when specifying both source and checksum" do it 'should use the specified checksum when source is first' do file[:source] = File.expand_path('/foo') file[:checksum] = :md5lite file[:checksum].should == :md5lite end it 'should use the specified checksum when source is last' do file[:checksum] = :md5lite file[:source] = File.expand_path('/foo') file[:checksum].should == :md5lite end end describe "when validating" do [[:source, :target], [:source, :content], [:target, :content]].each do |prop1,prop2| it "should fail if both #{prop1} and #{prop2} are specified" do file[prop1] = prop1 == :source ? File.expand_path("prop1 value") : "prop1 value" file[prop2] = "prop2 value" expect do file.validate end.to raise_error(Puppet::Error, /You cannot specify more than one of/) end end end end diff --git a/spec/unit/type/group_spec.rb b/spec/unit/type/group_spec.rb index afe28247a..e7da6abf6 100755 --- a/spec/unit/type/group_spec.rb +++ b/spec/unit/type/group_spec.rb @@ -1,63 +1,63 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Type.type(:group) do before do ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin") @class = Puppet::Type.type(:group) end it "should have a default provider" do @class.defaultprovider.should_not be_nil end it "should have a default provider inheriting from Puppet::Provider" do @class.defaultprovider.ancestors.should be_include(Puppet::Provider) end it "should have a system_groups feature" do @class.provider_feature(:system_groups).should_not be_nil end describe "when validating attributes" do [:name, :allowdupe].each do |param| it "should have a #{param} parameter" do @class.attrtype(param).should == :param end end [:ensure, :gid].each do |param| it "should have a #{param} property" do @class.attrtype(param).should == :property end end it "should convert gids provided as strings into integers" do @class.new(:name => "foo", :gid => "15")[:gid].should == 15 end it "should accepts gids provided as integers" do @class.new(:name => "foo", :gid => 15)[:gid].should == 15 end end - it "should have a boolean method for determining if duplicates are allowed", :'fails_on_ruby_1.9.2' => true do - @class.new(:name => "foo").methods.should be_include("allowdupe?") + it "should have a boolean method for determining if duplicates are allowed" do + @class.new(:name => "foo").should respond_to "allowdupe?" end - it "should have a boolean method for determining if system groups are allowed", :'fails_on_ruby_1.9.2' => true do - @class.new(:name => "foo").methods.should be_include("system?") + it "should have a boolean method for determining if system groups are allowed" do + @class.new(:name => "foo").should respond_to "system?" end it "should call 'create' to create the group" do group = @class.new(:name => "foo", :ensure => :present) group.provider.expects(:create) group.parameter(:ensure).sync end it "should call 'delete' to remove the group" do group = @class.new(:name => "foo", :ensure => :absent) group.provider.expects(:delete) group.parameter(:ensure).sync end end diff --git a/spec/unit/type/mailalias_spec.rb b/spec/unit/type/mailalias_spec.rb new file mode 100755 index 000000000..d4ed81949 --- /dev/null +++ b/spec/unit/type/mailalias_spec.rb @@ -0,0 +1,21 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +describe Puppet::Type.type(:mailalias) do + include PuppetSpec::Files + + let :target do tmpfile('mailalias') end + let :resource do + described_class.new(:name => "luke", :recipient => "yay", :target => target) + end + + it "should be initially absent" do + resource.retrieve_resource[:recipient].should == :absent + end + + it "should try and set the recipient when it does the sync" do + resource.retrieve_resource[:recipient].should == :absent + resource.property(:recipient).expects(:set).with(["yay"]) + resource.property(:recipient).sync + end +end diff --git a/spec/unit/type/resources_spec.rb b/spec/unit/type/resources_spec.rb index 652a6e8b7..ca2ffdd1f 100755 --- a/spec/unit/type/resources_spec.rb +++ b/spec/unit/type/resources_spec.rb @@ -1,101 +1,101 @@ #!/usr/bin/env rspec require 'spec_helper' resources = Puppet::Type.type(:resources) # There are still plenty of tests to port over from test/. describe resources do describe "when initializing" do it "should fail if the specified resource type does not exist" do Puppet::Type.stubs(:type).with { |x| x.to_s.downcase == "resources"}.returns resources Puppet::Type.expects(:type).with("nosuchtype").returns nil lambda { resources.new :name => "nosuchtype" }.should raise_error(Puppet::Error) end it "should not fail when the specified resource type exists" do lambda { resources.new :name => "file" }.should_not raise_error end it "should set its :resource_type attribute" do resources.new(:name => "file").resource_type.should == Puppet::Type.type(:file) end end describe "#generate" do before do @host1 = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1') @catalog = Puppet::Resource::Catalog.new @context = Puppet::Transaction.new(@catalog) end describe "when dealing with non-purging resources" do before do @resources = Puppet::Type.type(:resources).new(:name => 'host') end it "should not generate any resource" do @resources.generate.should be_empty end end describe "when the catalog contains a purging resource" do before do @resources = Puppet::Type.type(:resources).new(:name => 'host', :purge => true) @purgeable_resource = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1') @catalog.add_resource @resources end it "should not generate a duplicate of that resource" do Puppet::Type.type(:host).stubs(:instances).returns [@host1] @catalog.add_resource @host1 @resources.generate.collect { |r| r.ref }.should_not include(@host1.ref) end - it "should not include the skipped users", :'fails_on_ruby_1.9.2' => true do + it "should not include the skipped users" do res = Puppet::Type.type(:resources).new :name => :user, :purge => true res.catalog = Puppet::Resource::Catalog.new users = [ Puppet::Type.type(:user).new(:name => "root") ] Puppet::Type.type(:user).expects(:instances).returns users list = res.generate names = list.collect { |r| r[:name] } names.should_not be_include("root") end describe "when generating a purgeable resource" do it "should be included in the generated resources" do Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource] @resources.generate.collect { |r| r.ref }.should include(@purgeable_resource.ref) end end describe "when the instance's do not have an ensure property" do it "should not be included in the generated resources" do @no_ensure_resource = Puppet::Type.type(:exec).new(:name => "#{File.expand_path('/usr/bin/env')} echo") Puppet::Type.type(:host).stubs(:instances).returns [@no_ensure_resource] @resources.generate.collect { |r| r.ref }.should_not include(@no_ensure_resource.ref) end end describe "when the instance's ensure property does not accept absent" do it "should not be included in the generated resources" do @no_absent_resource = Puppet::Type.type(:service).new(:name => 'foobar') Puppet::Type.type(:host).stubs(:instances).returns [@no_absent_resource] @resources.generate.collect { |r| r.ref }.should_not include(@no_absent_resource.ref) end end describe "when checking the instance fails" do it "should not be included in the generated resources" do @purgeable_resource = Puppet::Type.type(:host).new(:name => 'foobar') Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource] @resources.expects(:check).with(@purgeable_resource).returns(false) @resources.generate.collect { |r| r.ref }.should_not include(@purgeable_resource.ref) end end end end end diff --git a/spec/unit/type/schedule_spec.rb b/spec/unit/type/schedule_spec.rb index 151c5cc19..c945b4b3a 100755 --- a/spec/unit/type/schedule_spec.rb +++ b/spec/unit/type/schedule_spec.rb @@ -1,425 +1,425 @@ #!/usr/bin/env rspec require 'spec_helper' module ScheduleTesting def diff(unit, incr, method, count) diff = Time.now.to_i.send(method, incr * count) Time.at(diff) end def day(method, count) diff(:hour, 3600 * 24, method, count) end def hour(method, count) diff(:hour, 3600, method, count) end def min(method, count) diff(:min, 60, method, count) end end describe Puppet::Type.type(:schedule) do before :each do Puppet[:ignoreschedules] = false @schedule = Puppet::Type.type(:schedule).new(:name => "testing") end describe Puppet::Type.type(:schedule) do include ScheduleTesting it "should apply to device" do @schedule.must be_appliable_to_device end it "should apply to host" do @schedule.must be_appliable_to_host end it "should default to :distance for period-matching" do @schedule[:periodmatch].must == :distance end it "should default to a :repeat of 1" do @schedule[:repeat].must == 1 end it "should never match when the period is :never" do @schedule[:period] = :never @schedule.must_not be_match end end describe Puppet::Type.type(:schedule), "when producing default schedules" do include ScheduleTesting %w{hourly daily weekly monthly never}.each do |period| period = period.to_sym it "should produce a #{period} schedule with the period set appropriately" do schedules = Puppet::Type.type(:schedule).mkdefaultschedules schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.must be_instance_of(Puppet::Type.type(:schedule)) end end it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do schedules = Puppet::Type.type(:schedule).mkdefaultschedules schedules.find { |s| s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2 }.must be_instance_of(Puppet::Type.type(:schedule)) end end describe Puppet::Type.type(:schedule), "when matching ranges" do include ScheduleTesting before do Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should match when the start time is before the current time and the end time is after the current time" do @schedule[:range] = "10:59:50 - 11:00:10" @schedule.must be_match end it "should not match when the start time is after the current time" do @schedule[:range] = "11:00:05 - 11:00:10" @schedule.must_not be_match end it "should not match when the end time is previous to the current time" do @schedule[:range] = "10:59:50 - 10:59:55" @schedule.must_not be_match end it "should throw an error if the upper limit is less than the lower limit" do pending "bug #7639" @schedule[:range] = "01:02:03 - 01:00:00" @schedule.must_throw Puppet::Error end it "should not match the current time fails between an array of ranges" do @schedule[:range] = ["4-6", "20-23"] @schedule.must_not be_match end it "should match the lower array of ranges" do @schedule[:range] = ["9-11", "14-16"] @schedule.must be_match end it "should match the upper array of ranges" do @schedule[:range] = ["4-6", "11-12"] @schedule.must be_match end end - describe Puppet::Type.type(:schedule), "when matching hourly by distance", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching hourly by distance" do include ScheduleTesting before do @schedule[:period] = :hourly @schedule[:periodmatch] = :distance Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should match when the previous time was an hour ago" do @schedule.must be_match(hour("-", 1)) end it "should not match when the previous time was now" do @schedule.must_not be_match(Time.now) end it "should not match when the previous time was 59 minutes ago" do @schedule.must_not be_match(min("-", 59)) end end - describe Puppet::Type.type(:schedule), "when matching daily by distance", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching daily by distance" do include ScheduleTesting before do @schedule[:period] = :daily @schedule[:periodmatch] = :distance Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should match when the previous time was one day ago" do @schedule.must be_match(day("-", 1)) end it "should not match when the previous time is now" do @schedule.must_not be_match(Time.now) end it "should not match when the previous time was 23 hours ago" do @schedule.must_not be_match(hour("-", 23)) end end - describe Puppet::Type.type(:schedule), "when matching weekly by distance", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching weekly by distance" do include ScheduleTesting before do @schedule[:period] = :weekly @schedule[:periodmatch] = :distance Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should match when the previous time was seven days ago" do @schedule.must be_match(day("-", 7)) end it "should not match when the previous time was now" do @schedule.must_not be_match(Time.now) end it "should not match when the previous time was six days ago" do @schedule.must_not be_match(day("-", 6)) end end - describe Puppet::Type.type(:schedule), "when matching monthly by distance", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching monthly by distance" do include ScheduleTesting before do @schedule[:period] = :monthly @schedule[:periodmatch] = :distance Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should match when the previous time was 32 days ago" do @schedule.must be_match(day("-", 32)) end it "should not match when the previous time was now" do @schedule.must_not be_match(Time.now) end it "should not match when the previous time was 27 days ago" do @schedule.must_not be_match(day("-", 27)) end end - describe Puppet::Type.type(:schedule), "when matching hourly by number", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching hourly by number" do include ScheduleTesting before do @schedule[:period] = :hourly @schedule[:periodmatch] = :number end it "should match if the times are one minute apart and the current minute is 0" do current = Time.utc(2008, 1, 1, 0, 0, 0) previous = Time.utc(2007, 12, 31, 23, 59, 0) Time.stubs(:now).returns(current) @schedule.must be_match(previous) end it "should not match if the times are 59 minutes apart and the current minute is 59" do current = Time.utc(2009, 2, 1, 12, 59, 0) previous = Time.utc(2009, 2, 1, 12, 0, 0) Time.stubs(:now).returns(current) @schedule.must_not be_match(previous) end end - describe Puppet::Type.type(:schedule), "when matching daily by number", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching daily by number" do include ScheduleTesting before do @schedule[:period] = :daily @schedule[:periodmatch] = :number end it "should match if the times are one minute apart and the current minute and hour are 0" do current = Time.utc(2010, "nov", 7, 0, 0, 0) # Now set the previous time to one minute before that previous = current - 60 Time.stubs(:now).returns(current) @schedule.must be_match(previous) end it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do # Reset the previous time to 00:00:00 previous = Time.utc(2010, "nov", 7, 0, 0, 0) # Set the current time to 23:59 now = previous + (23 * 3600) + (59 * 60) Time.stubs(:now).returns(now) @schedule.must_not be_match(previous) end end - describe Puppet::Type.type(:schedule), "when matching weekly by number", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching weekly by number" do include ScheduleTesting before do @schedule[:period] = :weekly @schedule[:periodmatch] = :number end it "should match if the previous time is prior to the most recent Sunday" do now = Time.utc(2010, "nov", 11, 0, 0, 0) # Thursday Time.stubs(:now).returns(now) previous = Time.utc(2010, "nov", 6, 23, 59, 59) # Sat @schedule.must be_match(previous) end it "should not match if the previous time is after the most recent Saturday" do now = Time.utc(2010, "nov", 11, 0, 0, 0) # Thursday Time.stubs(:now).returns(now) previous = Time.utc(2010, "nov", 7, 0, 0, 0) # Sunday @schedule.must_not be_match(previous) end end - describe Puppet::Type.type(:schedule), "when matching monthly by number", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching monthly by number" do include ScheduleTesting before do @schedule[:period] = :monthly @schedule[:periodmatch] = :number end it "should match when the previous time is prior to the first day of this month" do now = Time.utc(2010, "nov", 8, 00, 59, 59) Time.stubs(:now).returns(now) previous = Time.utc(2010, "oct", 31, 23, 59, 59) @schedule.must be_match(previous) end it "should not match when the previous time is after the last day of last month" do now = Time.utc(2010, "nov", 8, 00, 59, 59) Time.stubs(:now).returns(now) previous = Time.utc(2010, "nov", 1, 0, 0, 0) @schedule.must_not be_match(previous) end end - describe Puppet::Type.type(:schedule), "when matching with a repeat greater than one", :'fails_on_ruby_1.9.2' => true do + describe Puppet::Type.type(:schedule), "when matching with a repeat greater than one" do include ScheduleTesting before do @schedule[:period] = :daily @schedule[:repeat] = 2 Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should fail if the periodmatch is 'number'" do @schedule[:periodmatch] = :number proc { @schedule[:repeat] = 2 }.must raise_error(Puppet::Error) end it "should match if the previous run was further away than the distance divided by the repeat" do previous = Time.now - (3600 * 13) @schedule.must be_match(previous) end it "should not match if the previous run was closer than the distance divided by the repeat" do previous = Time.now - (3600 * 11) @schedule.must_not be_match(previous) end end describe Puppet::Type.type(:schedule), "when matching days of the week" do include ScheduleTesting before do # 2011-05-23 is a Monday Time.stubs(:now).returns(Time.local(2011, "may", 23, 11, 0, 0)) end it "should raise an error if the weekday is 'Someday'" do proc { @schedule[:weekday] = "Someday" }.should raise_error(Puppet::Error) end it "should raise an error if the weekday is '7'" do proc { @schedule[:weekday] = "7" }.should raise_error(Puppet::Error) end it "should accept all full weekday names as valid values" do proc { @schedule[:weekday] = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] }.should_not raise_error end it "should accept all short weekday names as valid values" do proc { @schedule[:weekday] = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] }.should_not raise_error end it "should match if the weekday is 'Monday'" do @schedule[:weekday] = "Monday" @schedule.match?.should be_true end it "should match if the weekday is 'Mon'" do @schedule[:weekday] = "Mon" @schedule.match?.should be_true end it "should match if the weekday is '1'" do @schedule[:weekday] = "1" @schedule.match?.should be_true end it "should not match if the weekday is Tuesday" do @schedule[:weekday] = "Tuesday" @schedule.should_not be_match end it "should match if weekday is ['Sun', 'Mon']" do @schedule[:weekday] = ["Sun", "Mon"] @schedule.match?.should be_true end it "should not match if weekday is ['Sun', 'Tue']" do @schedule[:weekday] = ["Sun", "Tue"] @schedule.should_not be_match end it "should match if the weekday is 'Monday'" do @schedule[:weekday] = "Monday" @schedule.match?.should be_true end it "should match if the weekday is 'Mon'" do @schedule[:weekday] = "Mon" @schedule.match?.should be_true end it "should match if the weekday is '1'" do @schedule[:weekday] = "1" @schedule.match?.should be_true end it "should not match if the weekday is Tuesday" do @schedule[:weekday] = "Tuesday" @schedule.should_not be_match end it "should match if weekday is ['Sun', 'Mon']" do @schedule[:weekday] = ["Sun", "Mon"] @schedule.match?.should be_true end end end diff --git a/spec/unit/type_spec.rb b/spec/unit/type_spec.rb index ed36ab061..49fd2938e 100755 --- a/spec/unit/type_spec.rb +++ b/spec/unit/type_spec.rb @@ -1,796 +1,961 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Type, :fails_on_windows => true do include PuppetSpec::Files it "should be Comparable" do a = Puppet::Type.type(:notify).new(:name => "a") b = Puppet::Type.type(:notify).new(:name => "b") c = Puppet::Type.type(:notify).new(:name => "c") [[a, b, c], [a, c, b], [b, a, c], [b, c, a], [c, a, b], [c, b, a]].each do |this| this.sort.should == [a, b, c] end a.should be < b a.should be < c b.should be > a b.should be < c c.should be > a c.should be > b [a, b, c].each {|x| a.should be <= x } [a, b, c].each {|x| c.should be >= x } b.should be_between(a, c) end it "should consider a parameter to be valid if it is a valid parameter" do Puppet::Type.type(:mount).should be_valid_parameter(:path) end it "should consider a parameter to be valid if it is a valid property" do Puppet::Type.type(:mount).should be_valid_parameter(:fstype) end it "should consider a parameter to be valid if it is a valid metaparam" do Puppet::Type.type(:mount).should be_valid_parameter(:noop) end it "should be able to retrieve a property by name" do resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present) resource.property(:fstype).must be_instance_of(Puppet::Type.type(:mount).attrclass(:fstype)) end it "should be able to retrieve a parameter by name" do resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present) resource.parameter(:name).must be_instance_of(Puppet::Type.type(:mount).attrclass(:name)) end it "should be able to retrieve a property by name using the :parameter method" do resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present) resource.parameter(:fstype).must be_instance_of(Puppet::Type.type(:mount).attrclass(:fstype)) end it "should be able to retrieve all set properties" do resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present) props = resource.properties props.should_not be_include(nil) [:fstype, :ensure, :pass].each do |name| props.should be_include(resource.parameter(name)) end end it "should have a method for setting default values for resources" do Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:set_default) end it "should do nothing for attributes that have no defaults and no specified value" do Puppet::Type.type(:mount).new(:name => "foo").parameter(:noop).should be_nil end it "should have a method for adding tags" do Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:tags) end it "should use the tagging module" do Puppet::Type.type(:mount).ancestors.should be_include(Puppet::Util::Tagging) end it "should delegate to the tagging module when tags are added" do resource = Puppet::Type.type(:mount).new(:name => "foo") resource.stubs(:tag).with(:mount) resource.expects(:tag).with(:tag1, :tag2) resource.tags = [:tag1,:tag2] end it "should add the current type as tag" do resource = Puppet::Type.type(:mount).new(:name => "foo") resource.stubs(:tag) resource.expects(:tag).with(:mount) resource.tags = [:tag1,:tag2] end it "should have a method to know if the resource is exported" do Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:exported?) end it "should have a method to know if the resource is virtual" do Puppet::Type.type(:mount).new(:name => "foo").should respond_to(:virtual?) end it "should consider its version to be its catalog version" do resource = Puppet::Type.type(:mount).new(:name => "foo") catalog = Puppet::Resource::Catalog.new catalog.version = 50 catalog.add_resource resource resource.version.should == 50 end it "should consider its version to be zero if it has no catalog" do Puppet::Type.type(:mount).new(:name => "foo").version.should == 0 end it "should provide source_descriptors" do resource = Puppet::Type.type(:mount).new(:name => "foo") catalog = Puppet::Resource::Catalog.new catalog.version = 50 catalog.add_resource resource resource.source_descriptors.should == {:tags=>["mount", "foo"], :path=>"/Mount[foo]"} end it "should consider its type to be the name of its class" do Puppet::Type.type(:mount).new(:name => "foo").type.should == :mount end it "should use any provided noop value" do Puppet::Type.type(:mount).new(:name => "foo", :noop => true).must be_noop end it "should use the global noop value if none is provided" do Puppet[:noop] = true Puppet::Type.type(:mount).new(:name => "foo").must be_noop end it "should not be noop if in a non-host_config catalog" do resource = Puppet::Type.type(:mount).new(:name => "foo") catalog = Puppet::Resource::Catalog.new catalog.add_resource resource resource.should_not be_noop end describe "when creating an event" do before do @resource = Puppet::Type.type(:mount).new :name => "foo" end it "should have the resource's reference as the resource" do @resource.event.resource.should == "Mount[foo]" end it "should have the resource's log level as the default log level" do @resource[:loglevel] = :warning @resource.event.default_log_level.should == :warning end {:file => "/my/file", :line => 50, :tags => %{foo bar}}.each do |attr, value| it "should set the #{attr}" do @resource.stubs(attr).returns value @resource.event.send(attr).should == value end end it "should allow specification of event attributes" do @resource.event(:status => "noop").status.should == "noop" end end describe "when creating a provider" do before :each do @type = Puppet::Type.newtype(:provider_test_type) do newparam(:name) { isnamevar } newparam(:foo) newproperty(:bar) end end after :each do @type.provider_hash.clear end describe "when determining if instances of the type are managed" do it "should not consider audit only resources to be managed" do @type.new(:name => "foo", :audit => 'all').managed?.should be_false end it "should not consider resources with only parameters to be managed" do @type.new(:name => "foo", :foo => 'did someone say food?').managed?.should be_false end it "should consider resources with any properties set to be managed" do @type.new(:name => "foo", :bar => 'Let us all go there').managed?.should be_true end end it "should have documentation for the 'provider' parameter if there are providers" do @type.provide(:test_provider) @type.paramdoc(:provider).should =~ /`provider_test_type`[\s\r]+resource/ end it "should not have documentation for the 'provider' parameter if there are no providers" do expect { @type.paramdoc(:provider) }.to raise_error(NoMethodError) end it "should create a subclass of Puppet::Provider for the provider" do provider = @type.provide(:test_provider) provider.ancestors.should include(Puppet::Provider) end it "should use a parent class if specified" do parent_provider = @type.provide(:parent_provider) child_provider = @type.provide(:child_provider, :parent => parent_provider) child_provider.ancestors.should include(parent_provider) end it "should use a parent class if specified by name" do parent_provider = @type.provide(:parent_provider) child_provider = @type.provide(:child_provider, :parent => :parent_provider) child_provider.ancestors.should include(parent_provider) end it "should raise an error when the parent class can't be found" do expect { @type.provide(:child_provider, :parent => :parent_provider) }.to raise_error(Puppet::DevError, /Could not find parent provider.+parent_provider/) end it "should ensure its type has a 'provider' parameter" do @type.provide(:test_provider) @type.parameters.should include(:provider) end it "should remove a previously registered provider with the same name" do old_provider = @type.provide(:test_provider) new_provider = @type.provide(:test_provider) old_provider.should_not equal(new_provider) end it "should register itself as a provider for the type" do provider = @type.provide(:test_provider) provider.should == @type.provider(:test_provider) end it "should create a provider when a provider with the same name previously failed" do @type.provide(:test_provider) do raise "failed to create this provider" end rescue nil provider = @type.provide(:test_provider) provider.ancestors.should include(Puppet::Provider) provider.should == @type.provider(:test_provider) end end describe "when choosing a default provider" do it "should choose the provider with the highest specificity" do # Make a fake type type = Puppet::Type.newtype(:defaultprovidertest) do newparam(:name) do end end basic = type.provide(:basic) {} greater = type.provide(:greater) {} basic.stubs(:specificity).returns 1 greater.stubs(:specificity).returns 2 type.defaultprovider.should equal(greater) end end describe "when initializing" do describe "and passed a Puppet::Resource instance" do it "should set its title to the title of the resource if the resource type is equal to the current type" do resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "/other"}) Puppet::Type.type(:mount).new(resource).title.should == "/foo" end it "should set its title to the resource reference if the resource type is not equal to the current type" do resource = Puppet::Resource.new(:user, "foo") Puppet::Type.type(:mount).new(resource).title.should == "User[foo]" end [:line, :file, :catalog, :exported, :virtual].each do |param| it "should copy '#{param}' from the resource if present" do resource = Puppet::Resource.new(:mount, "/foo") resource.send(param.to_s + "=", "foo") resource.send(param.to_s + "=", "foo") Puppet::Type.type(:mount).new(resource).send(param).should == "foo" end end it "should copy any tags from the resource" do resource = Puppet::Resource.new(:mount, "/foo") resource.tag "one", "two" tags = Puppet::Type.type(:mount).new(resource).tags tags.should be_include("one") tags.should be_include("two") end it "should copy the resource's parameters as its own" do resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:atboot => true, :fstype => "boo"}) params = Puppet::Type.type(:mount).new(resource).to_hash params[:fstype].should == "boo" params[:atboot].should == true end end describe "and passed a Hash" do it "should extract the title from the hash" do Puppet::Type.type(:mount).new(:title => "/yay").title.should == "/yay" end it "should work when hash keys are provided as strings" do Puppet::Type.type(:mount).new("title" => "/yay").title.should == "/yay" end it "should work when hash keys are provided as symbols" do Puppet::Type.type(:mount).new(:title => "/yay").title.should == "/yay" end it "should use the name from the hash as the title if no explicit title is provided" do Puppet::Type.type(:mount).new(:name => "/yay").title.should == "/yay" end it "should use the Resource Type's namevar to determine how to find the name in the hash" do yay = make_absolute('/yay') Puppet::Type.type(:file).new(:path => yay).title.should == yay end [:catalog].each do |param| it "should extract '#{param}' from the hash if present" do Puppet::Type.type(:mount).new(:name => "/yay", param => "foo").send(param).should == "foo" end end it "should use any remaining hash keys as its parameters" do resource = Puppet::Type.type(:mount).new(:title => "/foo", :catalog => "foo", :atboot => true, :fstype => "boo") resource[:fstype].must == "boo" resource[:atboot].must == true end end it "should fail if any invalid attributes have been provided" do lambda { Puppet::Type.type(:mount).new(:title => "/foo", :nosuchattr => "whatever") }.should raise_error(Puppet::Error) end it "should set its name to the resource's title if the resource does not have a :name or namevar parameter set" do resource = Puppet::Resource.new(:mount, "/foo") Puppet::Type.type(:mount).new(resource).name.should == "/foo" end it "should fail if no title, name, or namevar are provided" do lambda { Puppet::Type.type(:file).new(:atboot => true) }.should raise_error(Puppet::Error) end it "should set the attributes in the order returned by the class's :allattrs method" do Puppet::Type.type(:mount).stubs(:allattrs).returns([:name, :atboot, :noop]) resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "myname", :atboot => "myboot", :noop => "whatever"}) set = [] Puppet::Type.type(:mount).any_instance.stubs(:newattr).with do |param, hash| set << param true end.returns(stub_everything("a property")) Puppet::Type.type(:mount).new(resource) set[-1].should == :noop set[-2].should == :atboot end it "should always set the name and then default provider before anything else" do Puppet::Type.type(:mount).stubs(:allattrs).returns([:provider, :name, :atboot]) resource = Puppet::Resource.new(:mount, "/foo", :parameters => {:name => "myname", :atboot => "myboot"}) set = [] Puppet::Type.type(:mount).any_instance.stubs(:newattr).with do |param, hash| set << param true end.returns(stub_everything("a property")) Puppet::Type.type(:mount).new(resource) set[0].should == :name set[1].should == :provider end # This one is really hard to test :/ it "should set each default immediately if no value is provided" do defaults = [] Puppet::Type.type(:service).any_instance.stubs(:set_default).with { |value| defaults << value; true } Puppet::Type.type(:service).new :name => "whatever" defaults[0].should == :provider end it "should retain a copy of the originally provided parameters" do Puppet::Type.type(:mount).new(:name => "foo", :atboot => true, :noop => false).original_parameters.should == {:atboot => true, :noop => false} end it "should delete the name via the namevar from the originally provided parameters" do Puppet::Type.type(:file).new(:name => make_absolute('/foo')).original_parameters[:path].should be_nil end end it "should have a class method for converting a hash into a Puppet::Resource instance" do Puppet::Type.type(:mount).must respond_to(:hash2resource) end describe "when converting a hash to a Puppet::Resource instance" do before do @type = Puppet::Type.type(:mount) end it "should treat a :title key as the title of the resource" do @type.hash2resource(:name => "/foo", :title => "foo").title.should == "foo" end it "should use the name from the hash as the title if no explicit title is provided" do @type.hash2resource(:name => "foo").title.should == "foo" end it "should use the Resource Type's namevar to determine how to find the name in the hash" do @type.stubs(:key_attributes).returns([ :myname ]) @type.hash2resource(:myname => "foo").title.should == "foo" end [:catalog].each do |attr| it "should use any provided #{attr}" do @type.hash2resource(:name => "foo", attr => "eh").send(attr).should == "eh" end end it "should set all provided parameters on the resource" do @type.hash2resource(:name => "foo", :fstype => "boo", :boot => "fee").to_hash.should == {:name => "foo", :fstype => "boo", :boot => "fee"} end it "should not set the title as a parameter on the resource" do @type.hash2resource(:name => "foo", :title => "eh")[:title].should be_nil end it "should not set the catalog as a parameter on the resource" do @type.hash2resource(:name => "foo", :catalog => "eh")[:catalog].should be_nil end it "should treat hash keys equivalently whether provided as strings or symbols" do resource = @type.hash2resource("name" => "foo", "title" => "eh", "fstype" => "boo") resource.title.should == "eh" resource[:name].should == "foo" resource[:fstype].should == "boo" end end describe "when retrieving current property values" do before do @resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present) @resource.property(:ensure).stubs(:retrieve).returns :absent end it "should fail if its provider is unsuitable" do @resource = Puppet::Type.type(:mount).new(:name => "foo", :fstype => "bar", :pass => 1, :ensure => :present) @resource.provider.class.expects(:suitable?).returns false lambda { @resource.retrieve_resource }.should raise_error(Puppet::Error) end it "should return a Puppet::Resource instance with its type and title set appropriately" do result = @resource.retrieve_resource result.should be_instance_of(Puppet::Resource) result.type.should == "Mount" result.title.should == "foo" end it "should set the name of the returned resource if its own name and title differ" do @resource[:name] = "my name" @resource.title = "other name" @resource.retrieve_resource[:name].should == "my name" end it "should provide a value for all set properties" do values = @resource.retrieve_resource [:ensure, :fstype, :pass].each { |property| values[property].should_not be_nil } end it "should provide a value for 'ensure' even if no desired value is provided" do @resource = Puppet::Type.type(:file).new(:path => make_absolute("/my/file/that/can't/exist")) end it "should not call retrieve on non-ensure properties if the resource is absent and should consider the property absent" do @resource.property(:ensure).expects(:retrieve).returns :absent @resource.property(:fstype).expects(:retrieve).never @resource.retrieve_resource[:fstype].should == :absent end it "should include the result of retrieving each property's current value if the resource is present" do @resource.property(:ensure).expects(:retrieve).returns :present @resource.property(:fstype).expects(:retrieve).returns 15 @resource.retrieve_resource[:fstype] == 15 end end describe "#to_resource" do it "should return a Puppet::Resource that includes properties, parameters and tags" do type_resource = Puppet::Type.type(:mount).new( :ensure => :present, :name => "foo", :fstype => "bar", :remounts => true ) type_resource.tags = %w{bar baz} # If it's not a property it's a parameter type_resource.parameters[:remounts].should_not be_a(Puppet::Property) type_resource.parameters[:fstype].is_a?(Puppet::Property).should be_true type_resource.property(:ensure).expects(:retrieve).returns :present type_resource.property(:fstype).expects(:retrieve).returns 15 resource = type_resource.to_resource resource.should be_a Puppet::Resource resource[:fstype].should == 15 resource[:remounts].should == :true resource.tags.should =~ %w{foo bar baz mount} end end describe ".title_patterns" do describe "when there's one namevar" do before do @type_class = Puppet::Type.type(:notify) @type_class.stubs(:key_attributes).returns([:one]) end it "should have a default pattern for when there's one namevar" do patterns = @type_class.title_patterns patterns.length.should == 1 patterns[0].length.should == 2 end it "should have a regexp that captures the entire string" do patterns = @type_class.title_patterns string = "abc\n\tdef" patterns[0][0] =~ string $1.should == "abc\n\tdef" end end end describe "when in a catalog" do before do @catalog = Puppet::Resource::Catalog.new @container = Puppet::Type.type(:component).new(:name => "container") @one = Puppet::Type.type(:file).new(:path => make_absolute("/file/one")) @two = Puppet::Type.type(:file).new(:path => make_absolute("/file/two")) @catalog.add_resource @container @catalog.add_resource @one @catalog.add_resource @two @catalog.add_edge @container, @one @catalog.add_edge @container, @two end it "should have no parent if there is no in edge" do @container.parent.should be_nil end it "should set its parent to its in edge" do @one.parent.ref.should == @container.ref end after do @catalog.clear(true) end end it "should have a 'stage' metaparam" do Puppet::Type.metaparamclass(:stage).should be_instance_of(Class) end describe "#suitable?" do let(:type) { Puppet::Type.type(:file) } let(:resource) { type.new :path => tmpfile('suitable') } let(:provider) { resource.provider } it "should be suitable if its type doesn't use providers" do type.stubs(:paramclass).with(:provider).returns nil resource.should be_suitable end it "should be suitable if it has a provider which is suitable" do resource.should be_suitable end it "should not be suitable if it has a provider which is not suitable" do provider.class.stubs(:suitable?).returns false resource.should_not be_suitable end it "should be suitable if it does not have a provider and there is a default provider" do resource.stubs(:provider).returns nil resource.should be_suitable end it "should not be suitable if it doesn't have a provider and there is not default provider" do resource.stubs(:provider).returns nil type.stubs(:defaultprovider).returns nil resource.should_not be_suitable end end describe "::instances" do - it "should not fail if no suitable providers are found" do - fake_type = Puppet::Type.newtype(:type_spec_fake_type) do + after :each do Puppet::Type.rmtype(:type_spec_fake_type) end + let :type do + Puppet::Type.newtype(:type_spec_fake_type) do newparam(:name) do isnamevar end - newproperty(:prop1) do - end - provide(:fake1) do - confine :exists => '/no/such/file' + newproperty(:prop1) {} + end + + Puppet::Type.type(:type_spec_fake_type) + end + + it "should not fail if no suitable providers are found" do + type.provide(:fake1) do + confine :exists => '/no/such/file' + mk_resource_methods + end + + expect { type.instances.should == [] }.should_not raise_error + end + + context "with a default provider" do + before :each do + type.provide(:default) do + defaultfor :operatingsystem => Facter.value(:operatingsystem) mk_resource_methods + class << self + attr_accessor :names + end + def self.instance(name) + new(:name => name, :ensure => :present) + end + def self.instances + @instances ||= names.collect { |name| instance(name.to_s) } + end + + @names = [:one, :two] end end - expect { fake_type.instances }.should_not raise_error + it "should return only instances of the type" do + type.instances.should be_all {|x| x.is_a? type } + end + + it "should return instances from the default provider" do + type.instances.map(&:name).should == ["one", "two"] + end + + it "should return instances from all providers" do + type.provide(:fake1, :parent => :default) { @names = [:three, :four] } + type.instances.map(&:name).should == ["one", "two", "three", "four"] + end + + it "should not return instances from unsuitable providers" do + type.provide(:fake1, :parent => :default) do + @names = [:three, :four] + confine :exists => "/no/such/file" + end + + type.instances.map(&:name).should == ["one", "two"] + end end end describe "::ensurable?" do before :each do class TestEnsurableType < Puppet::Type def exists?; end def create; end def destroy; end end end it "is true if the class has exists?, create, and destroy methods defined" do TestEnsurableType.should be_ensurable end it "is false if exists? is not defined" do TestEnsurableType.class_eval { remove_method(:exists?) } TestEnsurableType.should_not be_ensurable end it "is false if create is not defined" do TestEnsurableType.class_eval { remove_method(:create) } TestEnsurableType.should_not be_ensurable end it "is false if destroy is not defined" do TestEnsurableType.class_eval { remove_method(:destroy) } TestEnsurableType.should_not be_ensurable end end end describe Puppet::Type::RelationshipMetaparam do include PuppetSpec::Files it "should be a subclass of Puppet::Parameter" do Puppet::Type::RelationshipMetaparam.superclass.should equal(Puppet::Parameter) end it "should be able to produce a list of subclasses" do Puppet::Type::RelationshipMetaparam.should respond_to(:subclasses) end describe "when munging relationships", :fails_on_windows => true do before do @path = make_absolute('/foo') @resource = Puppet::Type.type(:mount).new :name => @path @metaparam = Puppet::Type.metaparamclass(:require).new :resource => @resource end it "should accept Puppet::Resource instances" do ref = Puppet::Resource.new(:file, @path) @metaparam.munge(ref)[0].should equal(ref) end it "should turn any string into a Puppet::Resource" do @metaparam.munge("File[/ref]")[0].should be_instance_of(Puppet::Resource) end end it "should be able to validate relationships" do Puppet::Type.metaparamclass(:require).new(:resource => mock("resource")).should respond_to(:validate_relationship) end it "should fail if any specified resource is not found in the catalog" do catalog = mock 'catalog' resource = stub 'resource', :catalog => catalog, :ref => "resource" param = Puppet::Type.metaparamclass(:require).new(:resource => resource, :value => %w{Foo[bar] Class[test]}) catalog.expects(:resource).with("Foo[bar]").returns "something" catalog.expects(:resource).with("Class[Test]").returns nil param.expects(:fail).with { |string| string.include?("Class[Test]") } param.validate_relationship end end describe Puppet::Type.metaparamclass(:check) do include PuppetSpec::Files it "should warn and create an instance of ':audit'" do file = Puppet::Type.type(:file).new :path => make_absolute('/foo') file.expects(:warning) file[:check] = :mode file[:audit].should == [:mode] end end describe Puppet::Type.metaparamclass(:audit) do include PuppetSpec::Files before do @resource = Puppet::Type.type(:file).new :path => make_absolute('/foo') end it "should default to being nil" do @resource[:audit].should be_nil end it "should specify all possible properties when asked to audit all properties" do @resource[:audit] = :all list = @resource.class.properties.collect { |p| p.name } @resource[:audit].should == list end it "should accept the string 'all' to specify auditing all possible properties" do @resource[:audit] = 'all' list = @resource.class.properties.collect { |p| p.name } @resource[:audit].should == list end it "should fail if asked to audit an invalid property" do lambda { @resource[:audit] = :foobar }.should raise_error(Puppet::Error) end it "should create an attribute instance for each auditable property" do @resource[:audit] = :mode @resource.parameter(:mode).should_not be_nil end it "should accept properties specified as a string" do @resource[:audit] = "mode" @resource.parameter(:mode).should_not be_nil end it "should not create attribute instances for parameters, only properties" do @resource[:audit] = :noop @resource.parameter(:noop).should be_nil end describe "when generating the uniqueness key" do it "should include all of the key_attributes in alphabetical order by attribute name" do Puppet::Type.type(:file).stubs(:key_attributes).returns [:path, :mode, :owner] Puppet::Type.type(:file).stubs(:title_patterns).returns( [ [ /(.*)/, [ [:path, lambda{|x| x} ] ] ] ] ) myfile = make_absolute('/my/file') res = Puppet::Type.type(:file).new( :title => myfile, :path => myfile, :owner => 'root', :content => 'hello' ) res.uniqueness_key.should == [ nil, 'root', myfile] end end + + context "type attribute bracket methods" do + after :each do Puppet::Type.rmtype(:attributes) end + let :type do + Puppet::Type.newtype(:attributes) do + newparam(:name) {} + end + end + + it "should work with parameters" do + type.newparam(:param) {} + instance = type.new(:name => 'test') + + expect { instance[:param] = true }.should_not raise_error + expect { instance["param"] = true }.should_not raise_error + instance[:param].should == true + instance["param"].should == true + end + + it "should work with meta-parameters" do + instance = type.new(:name => 'test') + + expect { instance[:noop] = true }.should_not raise_error + expect { instance["noop"] = true }.should_not raise_error + instance[:noop].should == true + instance["noop"].should == true + end + + it "should work with properties" do + type.newproperty(:property) {} + instance = type.new(:name => 'test') + + expect { instance[:property] = true }.should_not raise_error + expect { instance["property"] = true }.should_not raise_error + instance.property(:property).must be + instance.should(:property).must be_true + end + + it "should handle proprieties correctly" do + # Order of assignment is significant in this test. + props = {} + [:one, :two, :three].each {|prop| type.newproperty(prop) {} } + instance = type.new(:name => "test") + + instance[:one] = "boo" + one = instance.property(:one) + instance.properties.must == [one] + + instance[:three] = "rah" + three = instance.property(:three) + instance.properties.must == [one, three] + + instance[:two] = "whee" + two = instance.property(:two) + instance.properties.must == [one, two, three] + end + + it "should handle parameter aliases correctly" do + type.newparam(:one) {} + type.newproperty(:two) {} + + type.set_attr_alias :three => :one + type.attr_alias(:three).must == :one + + type.set_attr_alias :four => :two + type.attr_alias(:four).must == :two + + type.attr_alias(:name).must_not be + + instance = type.new(:name => "my name") + instance.must be + + instance[:three] = "value three" + instance.value(:three).must == "value three" + instance.value(:one).must == "value three" + + instance[:four] = "value four" + instance.should(:four).must == "value four" + instance.value(:four).must == "value four" + instance.value(:two).must == "value four" + end + + it "newattr should handle required features correctly" do + Puppet::Util::Log.level = :debug + + type.feature :feature1, "one" + type.feature :feature2, "two" + + none = type.newproperty(:none) {} + one = type.newproperty(:one, :required_features => :feature1) {} + two = type.newproperty(:two, :required_features => [:feature1, :feature2]) {} + + nope = type.provide(:nope) {} + maybe = type.provide(:maybe) { has_features :feature1 } + yep = type.provide(:yep) { has_features :feature1, :feature2 } + + [nope, maybe, yep].each_with_index do |provider, i| + rsrc = type.new(:provider => provider.name, :name => "test#{i}", + :none => "a", :one => "b", :two => "c") + + rsrc.should(:none).must be + + if provider.declared_feature? :feature1 + rsrc.should(:one).must be + else + rsrc.should(:one).must_not be + @logs.find {|l| l.message =~ /not managing attribute one/ }.should be + end + + if provider.declared_feature? :feature2 + rsrc.should(:two).must be + else + rsrc.should(:two).must_not be + @logs.find {|l| l.message =~ /not managing attribute two/ }.should be + end + end + end + end end diff --git a/spec/unit/util/autoload_spec.rb b/spec/unit/util/autoload_spec.rb index 587d54796..8fbdfadb5 100755 --- a/spec/unit/util/autoload_spec.rb +++ b/spec/unit/util/autoload_spec.rb @@ -1,222 +1,222 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/autoload' describe Puppet::Util::Autoload do before do @autoload = Puppet::Util::Autoload.new("foo", "tmp") @autoload.stubs(:eachdir).yields "/my/dir" @loaded = {} @autoload.class.stubs(:loaded).returns(@loaded) end describe "when building the search path" do before :each do ## modulepath/libdir can't be used until after app settings are initialized, so we need to simulate that: Puppet.settings.expects(:app_defaults_initialized?).returns(true).at_least_once @dira = File.expand_path('/a') @dirb = File.expand_path('/b') @dirc = File.expand_path('/c') end it "should collect all of the plugins and lib directories that exist in the current environment's module path" do Puppet.settings.expects(:value).with(:environment).returns "foo" Puppet.settings.expects(:value).with(:modulepath, :foo).returns "#{@dira}#{File::PATH_SEPARATOR}#{@dirb}#{File::PATH_SEPARATOR}#{@dirc}" Dir.expects(:entries).with(@dira).returns %w{one two} Dir.expects(:entries).with(@dirb).returns %w{one two} FileTest.stubs(:directory?).returns false FileTest.expects(:directory?).with(@dira).returns true FileTest.expects(:directory?).with(@dirb).returns true ["#{@dira}/one/plugins", "#{@dira}/two/lib", "#{@dirb}/one/plugins", "#{@dirb}/two/lib"].each do |d| FileTest.expects(:directory?).with(d).returns true end @autoload.class.module_directories.should == ["#{@dira}/one/plugins", "#{@dira}/two/lib", "#{@dirb}/one/plugins", "#{@dirb}/two/lib"] end it "should not look for lib directories in directories starting with '.'" do Puppet.settings.expects(:value).with(:environment).returns "foo" Puppet.settings.expects(:value).with(:modulepath, :foo).returns @dira Dir.expects(:entries).with(@dira).returns %w{. ..} FileTest.expects(:directory?).with(@dira).returns true FileTest.expects(:directory?).with("#{@dira}/./lib").never FileTest.expects(:directory?).with("#{@dira}/./plugins").never FileTest.expects(:directory?).with("#{@dira}/../lib").never FileTest.expects(:directory?).with("#{@dira}/../plugins").never @autoload.class.module_directories end it "should include the module directories, the Puppet libdir, and all of the Ruby load directories" do Puppet[:libdir] = %w{/libdir1 /lib/dir/two /third/lib/dir}.join(File::PATH_SEPARATOR) @autoload.class.expects(:module_directories).returns %w{/one /two} @autoload.class.search_directories.should == %w{/one /two} + Puppet[:libdir].split(File::PATH_SEPARATOR) + $LOAD_PATH end end describe "when loading a file" do before do @autoload.class.stubs(:search_directories).returns %w{/a} FileTest.stubs(:directory?).returns true @time_a = Time.utc(2010, 'jan', 1, 6, 30) File.stubs(:mtime).returns @time_a end [RuntimeError, LoadError, SyntaxError].each do |error| it "should die with Puppet::Error if a #{error.to_s} exception is thrown" do File.stubs(:exist?).returns true Kernel.expects(:load).raises error lambda { @autoload.load("foo") }.should raise_error(Puppet::Error) end end it "should not raise an error if the file is missing" do @autoload.load("foo").should == false end it "should register loaded files with the autoloader" do File.stubs(:exist?).returns true Kernel.stubs(:load) @autoload.load("myfile") @autoload.class.loaded?("tmp/myfile.rb").should be $LOADED_FEATURES.delete("tmp/myfile.rb") end it "should register loaded files with the main loaded file list so they are not reloaded by ruby" do File.stubs(:exist?).returns true Kernel.stubs(:load) @autoload.load("myfile") $LOADED_FEATURES.should be_include("tmp/myfile.rb") $LOADED_FEATURES.delete("tmp/myfile.rb") end it "should load the first file in the searchpath" do @autoload.stubs(:search_directories).returns %w{/a /b} FileTest.stubs(:directory?).returns true File.stubs(:exist?).returns true Kernel.expects(:load).with("/a/tmp/myfile.rb", optionally(anything)) @autoload.load("myfile") $LOADED_FEATURES.delete("tmp/myfile.rb") end it "should treat equivalent paths to a loaded file as loaded" do File.stubs(:exist?).returns true Kernel.stubs(:load) @autoload.load("myfile") @autoload.class.loaded?("tmp/myfile").should be @autoload.class.loaded?("tmp/./myfile.rb").should be @autoload.class.loaded?("./tmp/myfile.rb").should be @autoload.class.loaded?("tmp/../tmp/myfile.rb").should be $LOADED_FEATURES.delete("tmp/myfile.rb") end end describe "when loading all files" do before do @autoload.class.stubs(:search_directories).returns %w{/a} FileTest.stubs(:directory?).returns true - Dir.stubs(:glob).returns "/a/foo/file.rb" + Dir.stubs(:glob).returns ["/a/foo/file.rb"] File.stubs(:exist?).returns true @time_a = Time.utc(2010, 'jan', 1, 6, 30) File.stubs(:mtime).returns @time_a @autoload.class.stubs(:loaded?).returns(false) end [RuntimeError, LoadError, SyntaxError].each do |error| - it "should die an if a #{error.to_s} exception is thrown", :'fails_on_ruby_1.9.2' => true do + it "should die an if a #{error.to_s} exception is thrown" do Kernel.expects(:load).raises error lambda { @autoload.loadall }.should raise_error(Puppet::Error) end end - it "should require the full path to the file", :'fails_on_ruby_1.9.2' => true do + it "should require the full path to the file" do Kernel.expects(:load).with("/a/foo/file.rb", optionally(anything)) @autoload.loadall end end describe "when reloading files" do before :each do @file_a = "/a/file.rb" @file_b = "/b/file.rb" @first_time = Time.utc(2010, 'jan', 1, 6, 30) @second_time = @first_time + 60 end after :each do $LOADED_FEATURES.delete("a/file.rb") $LOADED_FEATURES.delete("b/file.rb") end describe "in one directory" do before :each do @autoload.class.stubs(:search_directories).returns %w{/a} File.expects(:mtime).with(@file_a).returns(@first_time) @autoload.class.mark_loaded("file", @file_a) end it "should reload if mtime changes" do File.stubs(:mtime).with(@file_a).returns(@first_time + 60) File.stubs(:exist?).with(@file_a).returns true Kernel.expects(:load).with(@file_a, optionally(anything)) @autoload.class.reload_changed end it "should do nothing if the file is deleted" do File.stubs(:mtime).with(@file_a).raises(Errno::ENOENT) File.stubs(:exist?).with(@file_a).returns false Kernel.expects(:load).never @autoload.class.reload_changed end end describe "in two directories" do before :each do @autoload.class.stubs(:search_directories).returns %w{/a /b} end it "should load b/file when a/file is deleted" do File.expects(:mtime).with(@file_a).returns(@first_time) @autoload.class.mark_loaded("file", @file_a) File.stubs(:mtime).with(@file_a).raises(Errno::ENOENT) File.stubs(:exist?).with(@file_a).returns false File.stubs(:exist?).with(@file_b).returns true File.stubs(:mtime).with(@file_b).returns @first_time Kernel.expects(:load).with(@file_b, optionally(anything)) @autoload.class.reload_changed @autoload.class.send(:loaded)["file"].should == [@file_b, @first_time] end it "should load a/file when b/file is loaded and a/file is created" do File.stubs(:mtime).with(@file_b).returns @first_time File.stubs(:exist?).with(@file_b).returns true @autoload.class.mark_loaded("file", @file_b) File.stubs(:mtime).with(@file_a).returns @first_time File.stubs(:exist?).with(@file_a).returns true Kernel.expects(:load).with(@file_a, optionally(anything)) @autoload.class.reload_changed @autoload.class.send(:loaded)["file"].should == [@file_a, @first_time] end end end end diff --git a/spec/unit/util/file_locking_spec.rb b/spec/unit/util/file_locking_spec.rb deleted file mode 100755 index 1a12244b8..000000000 --- a/spec/unit/util/file_locking_spec.rb +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env rspec -require 'spec_helper' - -require 'puppet/util/file_locking' - -class FileLocker - include Puppet::Util::FileLocking -end - -describe Puppet::Util::FileLocking do - it "should have a module method for getting a read lock on files" do - Puppet::Util::FileLocking.should respond_to(:readlock) - end - - it "should have a module method for getting a write lock on files" do - Puppet::Util::FileLocking.should respond_to(:writelock) - end - - it "should have an instance method for getting a read lock on files", :'fails_on_ruby_1.9.2' => true do - FileLocker.new.private_methods.should be_include("readlock") - end - - it "should have an instance method for getting a write lock on files", :'fails_on_ruby_1.9.2' => true do - FileLocker.new.private_methods.should be_include("writelock") - end - - describe "when acquiring a read lock" do - before do - File.stubs(:exists?).with('/file').returns true - File.stubs(:file?).with('/file').returns true - end - - it "should use a global shared mutex" do - Puppet::Util.expects(:synchronize_on).with('/file',Sync::SH).once - Puppet::Util::FileLocking.readlock '/file' - end - - it "should use a shared lock on the file" do - Puppet::Util.expects(:synchronize_on).with('/file',Sync::SH).yields - - fh = mock 'filehandle' - File.expects(:open).with("/file").yields fh - fh.expects(:lock_shared).yields "locked_fh" - - result = nil - Puppet::Util::FileLocking.readlock('/file') { |l| result = l } - result.should == "locked_fh" - end - - it "should only work on regular files" do - File.expects(:file?).with('/file').returns false - proc { Puppet::Util::FileLocking.readlock('/file') }.should raise_error(ArgumentError) - end - - it "should create missing files" do - Puppet::Util.expects(:synchronize_on).with('/file',Sync::SH).yields - - File.expects(:exists?).with('/file').returns false - File.expects(:open).with('/file').once - - Puppet::Util::FileLocking.readlock('/file') - end - end - - describe "when acquiring a write lock" do - before do - Puppet::Util.stubs(:synchronize_on).yields - File.stubs(:file?).with('/file').returns true - File.stubs(:exists?).with('/file').returns true - end - - it "should fail if the parent directory does not exist" do - FileTest.expects(:directory?).with("/my/dir").returns false - File.stubs(:file?).with('/my/dir/file').returns true - File.stubs(:exists?).with('/my/dir/file').returns true - - lambda { Puppet::Util::FileLocking.writelock('/my/dir/file') }.should raise_error(Puppet::DevError) - end - - it "should use a global exclusive mutex" do - Puppet::Util.expects(:synchronize_on).with("/file",Sync::EX) - Puppet::Util::FileLocking.writelock '/file' - end - - it "should use any specified mode when opening the file" do - File.expects(:open).with("/file", File::Constants::CREAT | File::Constants::WRONLY , :mymode) - - Puppet::Util::FileLocking.writelock('/file', :mymode) - end - - it "should use the mode of the existing file if no mode is specified" do - File.expects(:stat).with("/file").returns(mock("stat", :mode => 0755)) - File.expects(:open).with("/file", File::Constants::CREAT | File::Constants::WRONLY, 0755) - - Puppet::Util::FileLocking.writelock('/file') - end - - it "should use 0600 as the mode if no mode is specified and the file does not exist" do - File.expects(:stat).raises(Errno::ENOENT) - File.expects(:open).with("/file", File::Constants::CREAT | File::Constants::WRONLY, 0600) - - Puppet::Util::FileLocking.writelock('/file') - end - - it "should create an exclusive file lock" do - fh = mock 'fh' - File.expects(:open).yields fh - fh.expects(:lock_exclusive) - - Puppet::Util::FileLocking.writelock('/file') - end - - it "should allow the caller to write to the locked file" do - fh = mock 'fh' - File.expects(:open).yields fh - - lfh = mock 'locked_filehandle' - fh.expects(:lock_exclusive).yields(lfh) - - lfh.stubs(:seek) - lfh.stubs(:truncate) - lfh.expects(:print).with "foo" - - Puppet::Util::FileLocking.writelock('/file') do |f| - f.print "foo" - end - end - - it "should truncate the file under an exclusive lock" do - fh = mock 'fh' - File.expects(:open).yields fh - - lfh = mock 'locked_filehandle' - fh.expects(:lock_exclusive).yields(lfh) - - lfh.expects(:seek).with(0, IO::SEEK_SET) - lfh.expects(:truncate).with(0) - lfh.stubs(:print) - - Puppet::Util::FileLocking.writelock('/file') do |f| - f.print "foo" - end - end - - it "should only work on regular files" do - File.expects(:file?).with('/file').returns false - proc { Puppet::Util::FileLocking.writelock('/file') }.should raise_error(ArgumentError) - end - - it "should create missing files" do - Puppet::Util.expects(:synchronize_on).with('/file',Sync::EX).yields - - File.expects(:exists?).with('/file').returns false - File.expects(:open).with('/file', File::Constants::CREAT | File::Constants::WRONLY, 0600).once - - Puppet::Util::FileLocking.writelock('/file') - end - end -end diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb index 6dd365e19..a74f768b2 100755 --- a/spec/unit/util/log_spec.rb +++ b/spec/unit/util/log_spec.rb @@ -1,259 +1,259 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/log' describe Puppet::Util::Log do include PuppetSpec::Files it "should write a given message to the specified destination" do arraydest = [] Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest)) Puppet::Util::Log.new(:level => :notice, :message => "foo") message = arraydest.last.message message.should == "foo" end describe ".setup_default" do it "should default to :syslog" do Puppet.features.stubs(:syslog?).returns(true) Puppet::Util::Log.expects(:newdestination).with(:syslog) Puppet::Util::Log.setup_default end it "should fall back to :file" do Puppet.features.stubs(:syslog?).returns(false) Puppet::Util::Log.expects(:newdestination).with(Puppet[:puppetdlog]) Puppet::Util::Log.setup_default end end describe Puppet::Util::Log::DestConsole do before do @console = Puppet::Util::Log::DestConsole.new end it "should colorize if Puppet[:color] is :ansi" do Puppet[:color] = :ansi @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m" end it "should colorize if Puppet[:color] is 'yes'" do Puppet[:color] = "yes" @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m" end it "should htmlize if Puppet[:color] is :html" do Puppet[:color] = :html @console.colorize(:alert, "abc").should == "abc" end it "should do nothing if Puppet[:color] is false" do Puppet[:color] = false @console.colorize(:alert, "abc").should == "abc" end it "should do nothing if Puppet[:color] is invalid" do Puppet[:color] = "invalid option" @console.colorize(:alert, "abc").should == "abc" end end describe Puppet::Util::Log::DestSyslog do before do @syslog = Puppet::Util::Log::DestSyslog.new end end describe "instances" do before do Puppet::Util::Log.stubs(:newmessage) end [:level, :message, :time, :remote].each do |attr| it "should have a #{attr} attribute" do log = Puppet::Util::Log.new :level => :notice, :message => "A test message" log.should respond_to(attr) log.should respond_to(attr.to_s + "=") end end it "should fail if created without a level" do lambda { Puppet::Util::Log.new(:message => "A test message") }.should raise_error(ArgumentError) end it "should fail if created without a message" do lambda { Puppet::Util::Log.new(:level => :notice) }.should raise_error(ArgumentError) end it "should make available the level passed in at initialization" do Puppet::Util::Log.new(:level => :notice, :message => "A test message").level.should == :notice end it "should make available the message passed in at initialization" do Puppet::Util::Log.new(:level => :notice, :message => "A test message").message.should == "A test message" end # LAK:NOTE I don't know why this behavior is here, I'm just testing what's in the code, # at least at first. it "should always convert messages to strings" do Puppet::Util::Log.new(:level => :notice, :message => :foo).message.should == "foo" end it "should flush the log queue when the first destination is specified" do Puppet::Util::Log.close_all Puppet::Util::Log.expects(:flushqueue) Puppet::Util::Log.newdestination(:console) end it "should convert the level to a symbol if it's passed in as a string" do Puppet::Util::Log.new(:level => "notice", :message => :foo).level.should == :notice end - it "should fail if the level is not a symbol or string", :'fails_on_ruby_1.9.2' => true do + it "should fail if the level is not a symbol or string" do lambda { Puppet::Util::Log.new(:level => 50, :message => :foo) }.should raise_error(ArgumentError) end it "should fail if the provided level is not valid" do Puppet::Util::Log.expects(:validlevel?).with(:notice).returns false lambda { Puppet::Util::Log.new(:level => :notice, :message => :foo) }.should raise_error(ArgumentError) end it "should set its time to the initialization time" do time = mock 'time' Time.expects(:now).returns time Puppet::Util::Log.new(:level => "notice", :message => :foo).time.should equal(time) end it "should make available any passed-in tags" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{foo bar}) log.tags.should be_include("foo") log.tags.should be_include("bar") end it "should use an passed-in source" do Puppet::Util::Log.any_instance.expects(:source=).with "foo" Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => "foo") end [:file, :line].each do |attr| it "should use #{attr} if provided" do Puppet::Util::Log.any_instance.expects(attr.to_s + "=").with "foo" Puppet::Util::Log.new(:level => "notice", :message => :foo, attr => "foo") end end it "should default to 'Puppet' as its source" do Puppet::Util::Log.new(:level => "notice", :message => :foo).source.should == "Puppet" end it "should register itself with Log" do Puppet::Util::Log.expects(:newmessage) Puppet::Util::Log.new(:level => "notice", :message => :foo) end it "should update Log autoflush when Puppet[:autoflush] is set" do Puppet::Util::Log.expects(:autoflush=).once.with(true) Puppet[:autoflush] = true end it "should have a method for determining if a tag is present" do Puppet::Util::Log.new(:level => "notice", :message => :foo).should respond_to(:tagged?) end it "should match a tag if any of the tags are equivalent to the passed tag as a string" do Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{one two}).should be_tagged(:one) end it "should tag itself with its log level" do Puppet::Util::Log.new(:level => "notice", :message => :foo).should be_tagged(:notice) end it "should return its message when converted to a string" do Puppet::Util::Log.new(:level => "notice", :message => :foo).to_s.should == "foo" end it "should include its time, source, level, and message when prepared for reporting" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo) report = log.to_report report.should be_include("notice") report.should be_include("foo") report.should be_include(log.source) report.should be_include(log.time.to_s) end it "should not create unsuitable log destinations" do Puppet.features.stubs(:syslog?).returns(false) Puppet::Util::Log::DestSyslog.expects(:suitable?) Puppet::Util::Log::DestSyslog.expects(:new).never Puppet::Util::Log.newdestination(:syslog) end describe "when setting the source as a RAL object" do it "should tag itself with any tags the source has" do source = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar") log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) source.tags.each do |tag| log.tags.should be_include(tag) end end it "should use the source_descriptors" do source = stub "source" source.stubs(:source_descriptors).returns(:tags => ["tag","tag2"], :path => "path", :version => 100) log = Puppet::Util::Log.new(:level => "notice", :message => :foo) log.expects(:tag).with("tag") log.expects(:tag).with("tag2") log.source = source log.source.should == "path" end it "should copy over any file and line information" do source = Puppet::Type.type(:file).new :path => make_absolute("/foo/bar") source.file = "/my/file" source.line = 50 log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) log.file.should == "/my/file" log.line.should == 50 end end describe "when setting the source as a non-RAL object" do it "should not try to copy over file, version, line, or tag information" do source = Puppet::Module.new("foo") source.expects(:file).never log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) end end end - describe "to_yaml", :'fails_on_ruby_1.9.2' => true do + describe "to_yaml" do it "should not include the @version attribute" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :version => 100) log.to_yaml_properties.should_not include('@version') end it "should include attributes @level, @message, @source, @tags, and @time" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :version => 100) - log.to_yaml_properties.should == %w{@level @message @source @tags @time} + log.to_yaml_properties.should == [:@level, :@message, :@source, :@tags, :@time] end it "should include attributes @file and @line if specified" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :file => "foo", :line => 35) - log.to_yaml_properties.should include('@file') - log.to_yaml_properties.should include('@line') + log.to_yaml_properties.should include(:@file) + log.to_yaml_properties.should include(:@line) end end end diff --git a/spec/unit/util/monkey_patches/lines_spec.rb b/spec/unit/util/monkey_patches/lines_spec.rb new file mode 100755 index 000000000..1ea379182 --- /dev/null +++ b/spec/unit/util/monkey_patches/lines_spec.rb @@ -0,0 +1,83 @@ +#!/usr/bin/env rspec +require 'spec_helper' +require 'puppet/util/monkey_patches/lines' + +class Puppet::Util::MonkeyPatches::Lines::TestHelper < String + include Puppet::Util::MonkeyPatches::Lines +end + +describe Puppet::Util::MonkeyPatches::Lines::TestHelper do + ["\n", "\n\n", "$", "$$", "@", "@@"].each do |sep| + context "with #{sep.inspect}" do + it "should delegate to each_line if given a block" do + subject.expects(:each_line).with(sep) + subject.lines(sep) do |x| nil end + end + + it "should delegate to each_line without a block" do + subject.expects(:enum_for).with(:each_line, sep) + subject.lines(sep) + end + + context "with one line" do + context "with trailing separator" do + subject { described_class.new("foo" + sep) } + + it "should yield the string" do + got = [] + subject.lines(sep) do |x| got << x end + got.should == ["foo#{sep}"] + end + + it "should return the string" do + subject.lines(sep).to_a.should == ["foo#{sep}"] + end + end + + context "without trailing separator" do + subject { described_class.new("foo") } + + it "should yield the string" do + got = [] + subject.lines(sep) do |x| got << x end + got.should == ["foo"] + end + + it "should return the string" do + subject.lines(sep).to_a.should == ["foo"] + end + end + end + + context "with multiple lines" do + context "with trailing separator" do + subject { described_class.new("foo#{sep}bar#{sep}baz#{sep}") } + + it "should yield the strings" do + got = [] + subject.lines(sep) do |x| got << x end + got.should == ["foo#{sep}", "bar#{sep}", "baz#{sep}"] + end + + it "should return the strings" do + subject.lines(sep).to_a.should == ["foo#{sep}", "bar#{sep}", "baz#{sep}"] + end + end + + context "without trailing separator" do + subject { described_class.new("foo#{sep}bar#{sep}baz") } + + it "should yield the strings" do + got = [] + subject.lines(sep) do |x| got << x end + got.should == ["foo#{sep}", "bar#{sep}", "baz"] + end + + it "should return the strings" do + subject.lines(sep).to_a.should == ["foo#{sep}", "bar#{sep}", "baz"] + end + end + end + end + end +end diff --git a/spec/unit/util/monkey_patches_spec.rb b/spec/unit/util/monkey_patches_spec.rb index 5e4e073d1..9757a4a7d 100755 --- a/spec/unit/util/monkey_patches_spec.rb +++ b/spec/unit/util/monkey_patches_spec.rb @@ -1,174 +1,214 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/monkey_patches' describe "yaml deserialization" do it "should call yaml_initialize when deserializing objects that have that method defined" do class Puppet::TestYamlInitializeClass attr_reader :foo def yaml_initialize(tag, var) var.should == {'foo' => 100} instance_variables.should == [] @foo = 200 end end obj = YAML.load("--- !ruby/object:Puppet::TestYamlInitializeClass\n foo: 100") obj.foo.should == 200 end it "should not call yaml_initialize if not defined" do class Puppet::TestYamlNonInitializeClass attr_reader :foo end obj = YAML.load("--- !ruby/object:Puppet::TestYamlNonInitializeClass\n foo: 100") obj.foo.should == 100 end end # In Ruby > 1.8.7 this is a builtin, otherwise we monkey patch the method in describe "Array#combination" do it "should fail if wrong number of arguments given" do lambda { [1,2,3].combination() }.should raise_error(ArgumentError, /wrong number/) lambda { [1,2,3].combination(1,2) }.should raise_error(ArgumentError, /wrong number/) end it "should return an empty array if combo size than array size or negative" do [1,2,3].combination(4).to_a.should == [] [1,2,3].combination(-1).to_a.should == [] end it "should return an empty array with an empty array if combo size == 0" do [1,2,3].combination(0).to_a.should == [[]] end it "should all provide all combinations of size passed in" do [1,2,3,4].combination(1).to_a.should == [[1], [2], [3], [4]] [1,2,3,4].combination(2).to_a.should == [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] [1,2,3,4].combination(3).to_a.should == [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] end end describe IO do include PuppetSpec::Files let(:file) { tmpfile('io-binary') } let(:content) { "\x01\x02\x03\x04" } describe "::binread" do it "should read in binary mode" do File.open(file, 'wb') {|f| f.write(content) } IO.binread(file).should == content end it "should read with a length and offset" do offset = 1 length = 2 File.open(file, 'wb') {|f| f.write(content) } IO.binread(file, length, offset).should == content[offset..length] end it "should raise an error if the file doesn't exist" do expect { IO.binread('/path/does/not/exist') }.to raise_error(Errno::ENOENT) end end describe "::binwrite" do it "should write in binary mode" do IO.binwrite(file, content).should == content.length File.open(file, 'rb') {|f| f.read.should == content } end - it "should write using an offset" do - offset = 1 - IO.binwrite(file, content, offset).should == content.length - offset - File.open(file, 'rb') {|f| f.read.should == content[offset..-1] } + (0..10).each do |offset| + it "should write correctly using an offset of #{offset}" do + IO.binwrite(file, content, offset).should == content.length + File.open(file, 'rb') {|f| f.read.should == ("\x00" * offset) + content } + end end - it "should raise an error if the file doesn't exist" do + context "truncation" do + let :input do "welcome to paradise, population ... YOU!" end + before :each do IO.binwrite(file, input) end + + it "should truncate if no offset is given" do + IO.binwrite(file, "boo").should == 3 + File.read(file).should == "boo" + end + + (0..10).each do |offset| + it "should not truncate if an offset of #{offset} is given" do + expect = input.dup + expect[offset, 3] = "BAM" + + IO.binwrite(file, "BAM", offset).should == 3 + File.read(file).should == expect + end + end + + it "should pad with NULL bytes if writing past EOF without truncate" do + expect = input + ("\x00" * 4) + "BAM" + IO.binwrite(file, "BAM", input.length + 4).should == 3 + File.read(file).should == expect + end + end + + it "should raise an error if the directory containing the file doesn't exist" do expect { IO.binwrite('/path/does/not/exist', 'foo') }.to raise_error(Errno::ENOENT) end end end describe Range do def do_test( range, other, expected ) result = range.intersection(other) result.should == expected end it "should return expected ranges for iterable things" do iterable_tests = { 1 .. 4 => nil, # before 11 .. 15 => nil, # after 1 .. 6 => 5 .. 6, # overlap_begin 9 .. 15 => 9 .. 10, # overlap_end 1 .. 5 => 5 .. 5, # overlap_begin_edge 10 .. 15 => 10 .. 10, # overlap_end_edge 5 .. 10 => 5 .. 10, # overlap_all 6 .. 9 => 6 .. 9, # overlap_inner 1 ... 5 => nil, # before (exclusive range) 1 ... 7 => 5 ... 7, # overlap_begin (exclusive range) 1 ... 6 => 5 ... 6, # overlap_begin_edge (exclusive range) 5 ... 11 => 5 .. 10, # overlap_all (exclusive range) 6 ... 10 => 6 ... 10, # overlap_inner (exclusive range) } iterable_tests.each do |other, expected| do_test( 5..10, other, expected ) do_test( other, 5..10, expected ) end end it "should return expected ranges for noniterable things" do inclusive_base_case = { 1.to_f .. 4.to_f => nil, # before 11.to_f .. 15.to_f => nil, # after 1.to_f .. 6.to_f => 5.to_f .. 6.to_f, # overlap_begin 9.to_f .. 15.to_f => 9.to_f .. 10.to_f, # overlap_end 1.to_f .. 5.to_f => 5.to_f .. 5.to_f, # overlap_begin_edge 10.to_f .. 15.to_f => 10.to_f .. 10.to_f, # overlap_end_edge 5.to_f .. 10.to_f => 5.to_f .. 10.to_f, # overlap_all 6.to_f .. 9.to_f => 6.to_f .. 9.to_f, # overlap_inner 1.to_f ... 5.to_f => nil, # before (exclusive range) 1.to_f ... 7.to_f => 5.to_f ... 7.to_f, # overlap_begin (exclusive range) 1.to_f ... 6.to_f => 5.to_f ... 6.to_f, # overlap_begin_edge (exclusive range) 5.to_f ... 11.to_f => 5.to_f .. 10.to_f, # overlap_all (exclusive range) 6.to_f ... 10.to_f => 6.to_f ... 10.to_f, # overlap_inner (exclusive range) } inclusive_base_case.each do |other, expected| do_test( 5.to_f..10.to_f, other, expected ) do_test( other, 5.to_f..10.to_f, expected ) end exclusive_base_case = { 1.to_f .. 4.to_f => nil, # before 11.to_f .. 15.to_f => nil, # after 1.to_f .. 6.to_f => 5.to_f .. 6.to_f, # overlap_begin 9.to_f .. 15.to_f => 9.to_f ... 10.to_f, # overlap_end 1.to_f .. 5.to_f => 5.to_f .. 5.to_f, # overlap_begin_edge 10.to_f .. 15.to_f => nil, # overlap_end_edge 5.to_f .. 10.to_f => 5.to_f ... 10.to_f, # overlap_all 6.to_f .. 9.to_f => 6.to_f .. 9.to_f, # overlap_inner 1.to_f ... 5.to_f => nil, # before (exclusive range) 1.to_f ... 7.to_f => 5.to_f ... 7.to_f, # overlap_begin (exclusive range) 1.to_f ... 6.to_f => 5.to_f ... 6.to_f, # overlap_begin_edge (exclusive range) 5.to_f ... 11.to_f => 5.to_f ... 10.to_f, # overlap_all (exclusive range) 6.to_f ... 10.to_f => 6.to_f ... 10.to_f, # overlap_inner (exclusive range) } exclusive_base_case.each do |other, expected| do_test( 5.to_f...10.to_f, other, expected ) do_test( other, 5.to_f...10.to_f, expected ) end end end + + +describe Object, "#instance_variables" do + it "should work with no instance variables" do + Object.new.instance_variables.should == [] + end + + it "should return symbols, not strings" do + o = Object.new + ["@foo", "@bar", "@baz"].map {|x| o.instance_variable_set(x, x) } + o.instance_variables.should =~ [:@foo, :@bar, :@baz] + end +end diff --git a/spec/unit/util/network_device/cisco/device_spec.rb b/spec/unit/util/network_device/cisco/device_spec.rb index 182d9ee71..cb2d161e3 100755 --- a/spec/unit/util/network_device/cisco/device_spec.rb +++ b/spec/unit/util/network_device/cisco/device_spec.rb @@ -1,408 +1,408 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/network_device/cisco/device' describe Puppet::Util::NetworkDevice::Cisco::Device do before(:each) do @transport = stub_everything 'transport', :is_a? => true, :command => "" @cisco = Puppet::Util::NetworkDevice::Cisco::Device.new("telnet://user:password@localhost:23/") @cisco.transport = @transport end describe "when creating the device" do it "should find the enable password from the url" do cisco = Puppet::Util::NetworkDevice::Cisco::Device.new("telnet://user:password@localhost:23/?enable=enable_password") cisco.enable_password.should == "enable_password" end it "should find the enable password from the options" do cisco = Puppet::Util::NetworkDevice::Cisco::Device.new("telnet://user:password@localhost:23/?enable=enable_password", :enable_password => "mypass") cisco.enable_password.should == "mypass" end end describe "when connecting to the physical device" do it "should connect to the transport" do @transport.expects(:connect) @cisco.command end it "should attempt to login" do @cisco.expects(:login) @cisco.command end it "should tell the device to not page" do @transport.expects(:command).with("terminal length 0") @cisco.command end it "should enter the enable password if returned prompt is not privileged" do @transport.stubs(:command).yields("Switch>").returns("") @cisco.expects(:enable) @cisco.command end it "should find device capabilities" do @cisco.expects(:find_capabilities) @cisco.command end it "should execute given command" do @transport.expects(:command).with("mycommand") @cisco.command("mycommand") end it "should yield to the command block if one is provided" do @transport.expects(:command).with("mycommand") @cisco.command do |c| c.command("mycommand") end end it "should close the device transport" do @transport.expects(:close) @cisco.command end describe "when login in" do it "should not login if transport handles login" do @transport.expects(:handles_login?).returns(true) @transport.expects(:command).never @transport.expects(:expect).never @cisco.login end it "should send username if one has been provided" do @transport.expects(:command).with("user", :prompt => /^Password:/) @cisco.login end it "should send password after the username" do @transport.expects(:command).with("user", :prompt => /^Password:/) @transport.expects(:command).with("password") @cisco.login end it "should expect the Password: prompt if no user was sent" do @cisco.url.user = '' @transport.expects(:expect).with(/^Password:/) @transport.expects(:command).with("password") @cisco.login end end describe "when entering enable password" do it "should raise an error if no enable password has been set" do @cisco.enable_password = nil lambda{ @cisco.enable }.should raise_error end it "should send the enable command and expect an enable prompt" do @cisco.enable_password = 'mypass' @transport.expects(:command).with("enable", :prompt => /^Password:/) @cisco.enable end it "should send the enable password" do @cisco.enable_password = 'mypass' @transport.stubs(:command).with("enable", :prompt => /^Password:/) @transport.expects(:command).with("mypass") @cisco.enable end end end describe "when finding network device capabilities" do it "should try to execute sh vlan brief" do @transport.expects(:command).with("sh vlan brief").returns("") @cisco.find_capabilities end it "should detect errors" do @transport.stubs(:command).with("sh vlan brief").returns(< "FastEthernet0/1", "Fa0/1" => "FastEthernet0/1", "FastEth 0/1" => "FastEthernet0/1", "Gi1" => "GigabitEthernet1", "Te2" => "TenGigabitEthernet2", "Di9" => "Dialer9", "Ethernet 0/0/1" => "Ethernet0/0/1", "E0" => "Ethernet0", "ATM 0/1.1" => "ATM0/1.1", "VLAN99" => "VLAN99" }.each do |input,expected| - it "should canonicalize #{input} to #{expected}", :'fails_on_ruby_1.9.2' => true do + it "should canonicalize #{input} to #{expected}" do @cisco.canonalize_ifname(input).should == expected end end describe "when updating device vlans" do describe "when removing a vlan" do it "should issue the no vlan command" do @transport.expects(:command).with("no vlan 200") @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :absent}) end end describe "when updating a vlan" do it "should issue the vlan command to enter global vlan modifications" do @transport.expects(:command).with("vlan 200") @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :present, :name => "200"}) end it "should issue the name command to modify the vlan description" do @transport.expects(:command).with("name myvlan") @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :present, :name => "200", :description => "myvlan"}) end end end describe "when parsing interface" do it "should parse interface output" do @cisco.expects(:parse_interface).returns({ :ensure => :present }) @cisco.interface("FastEthernet0/1").should == { :ensure => :present } end it "should parse trunking and merge results" do @cisco.stubs(:parse_interface).returns({ :ensure => :present }) @cisco.expects(:parse_trunking).returns({ :native_vlan => "100" }) @cisco.interface("FastEthernet0/1").should == { :ensure => :present, :native_vlan => "100" } end it "should return an absent interface if parse_interface returns nothing" do @cisco.stubs(:parse_interface).returns({}) @cisco.interface("FastEthernet0/1").should == { :ensure => :absent } end it "should parse ip address information and merge results" do @cisco.stubs(:parse_interface).returns({ :ensure => :present }) @cisco.expects(:parse_interface_config).returns({ :ipaddress => [24,IPAddr.new('192.168.0.24'), nil] }) @cisco.interface("FastEthernet0/1").should == { :ensure => :present, :ipaddress => [24,IPAddr.new('192.168.0.24'), nil] } end it "should parse the sh interface command" do @transport.stubs(:command).with("sh interface FastEthernet0/1").returns(< :absent, :duplex => :auto, :speed => :auto } end - it "should be able to parse the sh vlan brief command output", :'fails_on_ruby_1.9.2' => true do + it "should be able to parse the sh vlan brief command output" do @cisco.stubs(:support_vlan_brief?).returns(true) @transport.stubs(:command).with("sh vlan brief").returns(<{:status=>"active", :interfaces=>["FastEthernet0/1", "FastEthernet0/2"], :description=>"management", :name=>"100"}, "1"=>{:status=>"active", :interfaces=>["FastEthernet0/3", "FastEthernet0/4", "FastEthernet0/5", "FastEthernet0/6", "FastEthernet0/7", "FastEthernet0/8", "FastEthernet0/9", "FastEthernet0/10", "FastEthernet0/11", "FastEthernet0/12", "FastEthernet0/13", "FastEthernet0/14", "FastEthernet0/15", "FastEthernet0/16", "FastEthernet0/17", "FastEthernet0/18", "FastEthernet0/23", "FastEthernet0/24"], :description=>"default", :name=>"1"}, "10"=>{:status=>"active", :interfaces=>[], :description=>"VLAN0010", :name=>"10"}} end it "should parse trunk switchport information" do @transport.stubs(:command).with("sh interface FastEthernet0/21 switchport").returns(< :trunk, :encapsulation => :dot1q, :allowed_trunk_vlans=>:all, } end it "should parse trunk switchport information with allowed vlans" do @transport.stubs(:command).with("sh interface GigabitEthernet 0/1 switchport").returns(< :trunk, :encapsulation => :dot1q, :allowed_trunk_vlans=>"1,99", } end it "should parse access switchport information" do @transport.stubs(:command).with("sh interface FastEthernet0/1 switchport").returns(< :access, :native_vlan => "100" } end it "should parse ip addresses" do @transport.stubs(:command).with("sh running-config interface Vlan 1 | begin interface").returns(<[[24, IPAddr.new('192.168.0.24'), 'secondary'], [24, IPAddr.new('192.168.0.1'), nil], [64, IPAddr.new('2001:07a8:71c1::'), "eui-64"]]} end it "should parse etherchannel membership" do @transport.stubs(:command).with("sh running-config interface Gi0/17 | begin interface").returns(<"1"} end end describe "when finding device facts" do it "should delegate to the cisco facts entity" do facts = stub 'facts' Puppet::Util::NetworkDevice::Cisco::Facts.expects(:new).returns(facts) facts.expects(:retrieve).returns(:facts) @cisco.facts.should == :facts end end end diff --git a/spec/unit/util/network_device/transport/ssh_spec.rb b/spec/unit/util/network_device/transport/ssh_spec.rb index 04a86ba3f..d3e6b643b 100755 --- a/spec/unit/util/network_device/transport/ssh_spec.rb +++ b/spec/unit/util/network_device/transport/ssh_spec.rb @@ -1,218 +1,218 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/network_device/transport/ssh' -describe Puppet::Util::NetworkDevice::Transport::Ssh, :if => Puppet.features.ssh?, :'fails_on_ruby_1.9.2' => true do +describe Puppet::Util::NetworkDevice::Transport::Ssh, :if => Puppet.features.ssh? do before(:each) do @transport = Puppet::Util::NetworkDevice::Transport::Ssh.new() end it "should handle login through the transport" do @transport.should be_handles_login end it "should connect to the given host and port" do Net::SSH.expects(:start).with { |host, user, args| host == "localhost" && args[:port] == 22 }.returns stub_everything @transport.host = "localhost" @transport.port = 22 @transport.connect end it "should connect using the given username and password" do Net::SSH.expects(:start).with { |host, user, args| user == "user" && args[:password] == "pass" }.returns stub_everything @transport.user = "user" @transport.password = "pass" @transport.connect end it "should raise a Puppet::Error when encountering an authentication failure" do Net::SSH.expects(:start).raises Net::SSH::AuthenticationFailed @transport.host = "localhost" @transport.user = "user" lambda { @transport.connect }.should raise_error Puppet::Error end describe "when connected" do before(:each) do @ssh = stub_everything 'ssh' @channel = stub_everything 'channel' Net::SSH.stubs(:start).returns @ssh @ssh.stubs(:open_channel).yields(@channel) @transport.stubs(:expect) end it "should open a channel" do @ssh.expects(:open_channel) @transport.connect end it "should request a pty" do @channel.expects(:request_pty) @transport.connect end it "should create a shell channel" do @channel.expects(:send_channel_request).with("shell") @transport.connect end it "should raise an error if shell channel creation fails" do @channel.expects(:send_channel_request).with("shell").yields(@channel, false) lambda { @transport.connect }.should raise_error end it "should register an on_data and on_extended_data callback" do @channel.expects(:send_channel_request).with("shell").yields(@channel, true) @channel.expects(:on_data) @channel.expects(:on_extended_data) @transport.connect end it "should accumulate data to the buffer on data" do @channel.expects(:send_channel_request).with("shell").yields(@channel, true) @channel.expects(:on_data).yields(@channel, "data") @transport.connect @transport.buf.should == "data" end it "should accumulate data to the buffer on extended data" do @channel.expects(:send_channel_request).with("shell").yields(@channel, true) @channel.expects(:on_extended_data).yields(@channel, 1, "data") @transport.connect @transport.buf.should == "data" end it "should mark eof on close" do @channel.expects(:send_channel_request).with("shell").yields(@channel, true) @channel.expects(:on_close).yields(@channel) @transport.connect @transport.should be_eof end it "should expect output to conform to the default prompt" do @channel.expects(:send_channel_request).with("shell").yields(@channel, true) @transport.expects(:default_prompt).returns("prompt") @transport.expects(:expect).with("prompt") @transport.connect end it "should start the ssh loop" do @ssh.expects(:loop) @transport.connect end end describe "when closing" do before(:each) do @ssh = stub_everything 'ssh' @channel = stub_everything 'channel' Net::SSH.stubs(:start).returns @ssh @ssh.stubs(:open_channel).yields(@channel) @channel.stubs(:send_channel_request).with("shell").yields(@channel, true) @transport.stubs(:expect) @transport.connect end it "should close the channel" do @channel.expects(:close) @transport.close end it "should close the ssh session" do @ssh.expects(:close) @transport.close end end describe "when sending commands" do before(:each) do @ssh = stub_everything 'ssh' @channel = stub_everything 'channel' Net::SSH.stubs(:start).returns @ssh @ssh.stubs(:open_channel).yields(@channel) @channel.stubs(:send_channel_request).with("shell").yields(@channel, true) @transport.stubs(:expect) @transport.connect end it "should send data to the ssh channel" do @channel.expects(:send_data).with("data\n") @transport.command("data") end it "should expect the default prompt afterward" do @transport.expects(:default_prompt).returns("prompt") @transport.expects(:expect).with("prompt") @transport.command("data") end it "should expect the given prompt" do @transport.expects(:expect).with("myprompt") @transport.command("data", :prompt => "myprompt") end it "should yield the buffer output to given block" do @transport.expects(:expect).yields("output") @transport.command("data") do |out| out.should == "output" end end it "should return buffer output" do @transport.expects(:expect).returns("output") @transport.command("data").should == "output" end end describe "when expecting output" do before(:each) do @connection = stub_everything 'connection' @socket = stub_everything 'socket' transport = stub 'transport', :socket => @socket @ssh = stub_everything 'ssh', :transport => transport @channel = stub_everything 'channel', :connection => @connection @transport.ssh = @ssh @transport.channel = @channel end it "should process the ssh event loop" do IO.stubs(:select) @transport.buf = "output" @transport.expects(:process_ssh) @transport.expect(/output/) end it "should return the output" do IO.stubs(:select) @transport.buf = "output" @transport.stubs(:process_ssh) @transport.expect(/output/).should == "output" end it "should return the output" do IO.stubs(:select) @transport.buf = "output" @transport.stubs(:process_ssh) @transport.expect(/output/).should == "output" end describe "when processing the ssh loop" do it "should advance one tick in the ssh event loop and exit on eof" do @transport.buf = '' @connection.expects(:process).then.raises(EOFError) @transport.process_ssh end end end end diff --git a/spec/unit/util/pson_spec.rb b/spec/unit/util/pson_spec.rb index 9331b9416..151b59386 100755 --- a/spec/unit/util/pson_spec.rb +++ b/spec/unit/util/pson_spec.rb @@ -1,52 +1,64 @@ #!/usr/bin/env rspec +# Encoding: UTF-8 require 'spec_helper' require 'puppet/util/pson' class PsonUtil include Puppet::Util::Pson end -describe Puppet::Util::Pson, :'fails_on_ruby_1.9.2' => true do +describe Puppet::Util::Pson do it "should fail if no data is provided" do - lambda { PsonUtil.new.pson_create("type" => "foo") }.should raise_error(ArgumentError) + expect { PsonUtil.new.pson_create("type" => "foo") }.should raise_error(ArgumentError) end it "should call 'from_pson' with the provided data" do pson = PsonUtil.new pson.expects(:from_pson).with("mydata") pson.pson_create("type" => "foo", "data" => "mydata") end - - { + { 'foo' => '"foo"', 1 => '1', "\x80" => "\"\x80\"", [] => '[]' - }.each { |str,pson| + }.each do |str, expect| it "should be able to encode #{str.inspect}" do - str.to_pson.should == pson + got = str.to_pson + if got.respond_to? :force_encoding + got.force_encoding('binary').should == expect.force_encoding('binary') + else + got.should == expect + end end - } + end it "should be able to handle arbitrary binary data" do bin_string = (1..20000).collect { |i| ((17*i+13*i*i) % 255).chr }.join - PSON.parse(%Q{{ "type": "foo", "data": #{bin_string.to_pson} }})["data"].should == bin_string + parsed = PSON.parse(%Q{{ "type": "foo", "data": #{bin_string.to_pson} }})["data"] + + if parsed.respond_to? :force_encoding + parsed.force_encoding('binary') + bin_string.force_encoding('binary') + end + + parsed.should == bin_string end it "should be able to handle UTF8 that isn't a real unicode character" do s = ["\355\274\267"] PSON.parse( [s].to_pson ).should == [s] end it "should be able to handle UTF8 for \\xFF" do s = ["\xc3\xbf"] PSON.parse( [s].to_pson ).should == [s] end it "should be able to handle invalid UTF8 bytes" do s = ["\xc3\xc3"] PSON.parse( [s].to_pson ).should == [s] end end diff --git a/spec/unit/util/queue/stomp_spec.rb b/spec/unit/util/queue/stomp_spec.rb index 7730ab7cb..c4dc525ca 100755 --- a/spec/unit/util/queue/stomp_spec.rb +++ b/spec/unit/util/queue/stomp_spec.rb @@ -1,140 +1,140 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/queue' -describe Puppet::Util::Queue, :if => Puppet.features.stomp?, :'fails_on_ruby_1.9.2' => true do +describe Puppet::Util::Queue, :if => Puppet.features.stomp? do it 'should load :stomp client appropriately' do Puppet.settings.stubs(:value).returns 'faux_queue_source' Puppet::Util::Queue.queue_type_to_class(:stomp).name.should == 'Puppet::Util::Queue::Stomp' end end -describe 'Puppet::Util::Queue::Stomp', :if => Puppet.features.stomp?, :'fails_on_ruby_1.9.2' => true do +describe 'Puppet::Util::Queue::Stomp', :if => Puppet.features.stomp? do before do # So we make sure we never create a real client instance. # Otherwise we'll try to connect, and that's bad. Stomp::Client.stubs(:new).returns stub("client", :publish => true) end it 'should be registered with Puppet::Util::Queue as :stomp type' do Puppet::Util::Queue.queue_type_to_class(:stomp).should == Puppet::Util::Queue::Stomp end describe "when initializing" do it "should create a Stomp client instance" do Stomp::Client.expects(:new).returns stub("stomp_client", :publish => true) Puppet::Util::Queue::Stomp.new end it "should provide helpful failures when the queue source is not a valid source" do # Stub rather than expect, so we can include the source in the error Puppet.settings.stubs(:value).with(:queue_source).returns "-----" lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError) end it "should fail unless the queue source is a stomp URL" do # Stub rather than expect, so we can include the source in the error Puppet.settings.stubs(:value).with(:queue_source).returns "http://foo/bar" lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError) end it "should fail somewhat helpfully if the Stomp client cannot be created" do Stomp::Client.expects(:new).raises RuntimeError lambda { Puppet::Util::Queue::Stomp.new }.should raise_error(ArgumentError) end list = %w{user password host port} {"user" => "myuser", "password" => "mypass", "host" => "foohost", "port" => 42}.each do |name, value| it "should use the #{name} from the queue source as the queueing #{name}" do Puppet.settings.expects(:value).with(:queue_source).returns "stomp://myuser:mypass@foohost:42/" Stomp::Client.expects(:new).with { |*args| args[list.index(name)] == value } Puppet::Util::Queue::Stomp.new end end it "should create a reliable client instance" do Puppet.settings.expects(:value).with(:queue_source).returns "stomp://myuser@foohost:42/" Stomp::Client.expects(:new).with { |*args| args[4] == true } Puppet::Util::Queue::Stomp.new end end describe "when publishing a message" do before do @client = stub 'client', :publish => true Stomp::Client.stubs(:new).returns @client @queue = Puppet::Util::Queue::Stomp.new end it "should publish it to the queue client instance" do @client.expects(:publish).with { |queue, msg, options| msg == "Smite!" } @queue.publish_message('fooqueue', 'Smite!') end it "should publish it to the transformed queue name" do @client.expects(:publish).with { |queue, msg, options| queue == "/queue/fooqueue" } @queue.publish_message('fooqueue', 'Smite!') end it "should publish it as a persistent message" do @client.expects(:publish).with { |queue, msg, options| options[:persistent] == true } @queue.publish_message('fooqueue', 'Smite!') end it "should use send when the gem does not support publish" do Stomp::Client.stubs(:new).returns(stub('client', :send => true)) Puppet::Util::Queue::Stomp.new.publish_message('fooqueue', 'Smite!') end end describe "when subscribing to a queue" do before do @client = stub 'client', :acknowledge => true, :publish => true Stomp::Client.stubs(:new).returns @client @queue = Puppet::Util::Queue::Stomp.new end it "should subscribe via the queue client instance" do @client.expects(:subscribe) @queue.subscribe('fooqueue') end it "should subscribe to the transformed queue name" do @client.expects(:subscribe).with { |queue, options| queue == "/queue/fooqueue" } @queue.subscribe('fooqueue') end it "should specify that its messages should be acknowledged" do @client.expects(:subscribe).with { |queue, options| options[:ack] == :client } @queue.subscribe('fooqueue') end it "should yield the body of any received message" do message = mock 'message' message.expects(:body).returns "mybody" @client.expects(:subscribe).yields(message) body = nil @queue.subscribe('fooqueue') { |b| body = b } body.should == "mybody" end it "should acknowledge all successfully processed messages" do message = stub 'message', :body => "mybode" @client.stubs(:subscribe).yields(message) @client.expects(:acknowledge).with(message) @queue.subscribe('fooqueue') { |b| "eh" } end end it 'should transform the simple queue name to "/queue/"' do Puppet::Util::Queue::Stomp.new.stompify_target('blah').should == '/queue/blah' end end diff --git a/spec/unit/util/rdoc/parser_spec.rb b/spec/unit/util/rdoc/parser_spec.rb index f95873080..c24adf763 100755 --- a/spec/unit/util/rdoc/parser_spec.rb +++ b/spec/unit/util/rdoc/parser_spec.rb @@ -1,592 +1,594 @@ #!/usr/bin/env rspec require 'spec_helper' -require 'puppet/resource/type_collection' -require 'puppet/util/rdoc/parser' -require 'puppet/util/rdoc/code_objects' -require 'rdoc/options' -require 'rdoc/rdoc' +describe "RDoc::Parser", :if => Puppet.features.rdoc1? do + before :all do + require 'puppet/resource/type_collection' + require 'puppet/util/rdoc/parser' + require 'puppet/util/rdoc/code_objects' + require 'rdoc/options' + require 'rdoc/rdoc' + end -describe RDoc::Parser, :'fails_on_ruby_1.9.2' => true do include PuppetSpec::Files before :each do File.stubs(:stat).with("init.pp") @top_level = stub_everything 'toplevel', :file_relative_name => "init.pp" @parser = RDoc::Parser.new(@top_level, "module/manifests/init.pp", nil, Options.instance, RDoc::Stats.new) end describe "when scanning files" do it "should parse puppet files with the puppet parser" do @parser.stubs(:scan_top_level) parser = stub 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')).at_least_once parser.expects(:file=).with("module/manifests/init.pp") parser.expects(:file=).with(File.expand_path("/dev/null/manifests/site.pp")) @parser.scan end it "should scan the ast for Puppet files" do parser = stub_everything 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')).at_least_once @parser.expects(:scan_top_level) @parser.scan end it "should return a PuppetTopLevel to RDoc" do parser = stub_everything 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')).at_least_once @parser.expects(:scan_top_level) @parser.scan.should be_a(RDoc::PuppetTopLevel) end it "should scan the top level even if the file has already parsed" do known_type = stub 'known_types' env = stub 'env' Puppet::Node::Environment.stubs(:new).returns(env) env.stubs(:known_resource_types).returns(known_type) known_type.expects(:watching_file?).with("module/manifests/init.pp").returns(true) @parser.expects(:scan_top_level) @parser.scan end end describe "when scanning top level entities" do before :each do @resource_type_collection = resource_type_collection = stub_everything('resource_type_collection') @parser.instance_eval { @known_resource_types = resource_type_collection } @parser.stubs(:split_module).returns("module") @topcontainer = stub_everything 'topcontainer' @container = stub_everything 'container' @module = stub_everything 'module' @container.stubs(:add_module).returns(@module) @parser.stubs(:get_class_or_module).returns([@container, "module"]) end it "should read any present README as module documentation" do FileTest.stubs(:readable?).with("module/README").returns(true) FileTest.stubs(:readable?).with("module/README.rdoc").returns(false) File.stubs(:open).returns("readme") @parser.stubs(:parse_elements) @module.expects(:comment=).with("readme") @parser.scan_top_level(@topcontainer) end it "should read any present README.rdoc as module documentation" do FileTest.stubs(:readable?).with("module/README.rdoc").returns(true) FileTest.stubs(:readable?).with("module/README").returns(false) File.stubs(:open).returns("readme") @parser.stubs(:parse_elements) @module.expects(:comment=).with("readme") @parser.scan_top_level(@topcontainer) end it "should prefer README.rdoc over README as module documentation" do FileTest.stubs(:readable?).with("module/README.rdoc").returns(true) FileTest.stubs(:readable?).with("module/README").returns(true) File.stubs(:open).with("module/README", "r").returns("readme") File.stubs(:open).with("module/README.rdoc", "r").returns("readme.rdoc") @parser.stubs(:parse_elements) @module.expects(:comment=).with("readme.rdoc") @parser.scan_top_level(@topcontainer) end it "should tell the container its module name" do @parser.stubs(:parse_elements) @topcontainer.expects(:module_name=).with("module") @parser.scan_top_level(@topcontainer) end it "should not document our toplevel if it isn't a valid module" do @parser.stubs(:split_module).returns(nil) @topcontainer.expects(:document_self=).with(false) @parser.expects(:parse_elements).never @parser.scan_top_level(@topcontainer) end it "should set the module as global if we parse the global manifests (ie __site__ module)" do @parser.stubs(:split_module).returns(RDoc::Parser::SITE) @parser.stubs(:parse_elements) @topcontainer.expects(:global=).with(true) @parser.scan_top_level(@topcontainer) end it "should attach this module container to the toplevel container" do @parser.stubs(:parse_elements) @container.expects(:add_module).with(RDoc::PuppetModule, "module").returns(@module) @parser.scan_top_level(@topcontainer) end it "should defer ast parsing to parse_elements for this module" do @parser.expects(:parse_elements).with(@module) @parser.scan_top_level(@topcontainer) end it "should defer plugins parsing to parse_plugins for this module" do @parser.input_file_name = "module/lib/puppet/parser/function.rb" @parser.expects(:parse_plugins).with(@module) @parser.scan_top_level(@topcontainer) end end describe "when finding modules from filepath" do before :each do Puppet::Node::Environment.any_instance.stubs(:modulepath).returns("/path/to/modules") end it "should return the module name for modulized puppet manifests" do File.stubs(:expand_path).returns("/path/to/module/manifests/init.pp") File.stubs(:identical?).with("/path/to", "/path/to/modules").returns(true) @parser.split_module("/path/to/modules/mymodule/manifests/init.pp").should == "module" end it "should return for manifests not under module path" do File.stubs(:expand_path).returns("/path/to/manifests/init.pp") File.stubs(:identical?).returns(false) @parser.split_module("/path/to/manifests/init.pp").should == RDoc::Parser::SITE end it "should handle windows paths with drive letters", :if => Puppet.features.microsoft_windows? do @parser.split_module("C:/temp/init.pp").should == RDoc::Parser::SITE end end describe "when parsing AST elements" do before :each do @klass = stub_everything 'klass', :file => "module/manifests/init.pp", :name => "myclass", :type => :hostclass @definition = stub_everything 'definition', :file => "module/manifests/init.pp", :type => :definition, :name => "mydef" @node = stub_everything 'node', :file => "module/manifests/init.pp", :type => :node, :name => "mynode" @resource_type_collection = resource_type_collection = Puppet::Resource::TypeCollection.new("env") @parser.instance_eval { @known_resource_types = resource_type_collection } @container = stub_everything 'container' end it "should document classes in the parsed file" do @resource_type_collection.add_hostclass(@klass) @parser.expects(:document_class).with("myclass", @klass, @container) @parser.parse_elements(@container) end it "should not document class parsed in an other file" do @klass.stubs(:file).returns("/not/same/path/file.pp") @resource_type_collection.add_hostclass(@klass) @parser.expects(:document_class).with("myclass", @klass, @container).never @parser.parse_elements(@container) end it "should document vardefs for the main class" do @klass.stubs(:name).returns :main @resource_type_collection.add_hostclass(@klass) code = stub 'code', :is_a? => false @klass.stubs(:name).returns("") @klass.stubs(:code).returns(code) @parser.expects(:scan_for_vardef).with(@container, code) @parser.parse_elements(@container) end it "should document definitions in the parsed file" do @resource_type_collection.add_definition(@definition) @parser.expects(:document_define).with("mydef", @definition, @container) @parser.parse_elements(@container) end it "should not document definitions parsed in an other file" do @definition.stubs(:file).returns("/not/same/path/file.pp") @resource_type_collection.add_definition(@definition) @parser.expects(:document_define).with("mydef", @definition, @container).never @parser.parse_elements(@container) end it "should document nodes in the parsed file" do @resource_type_collection.add_node(@node) @parser.expects(:document_node).with("mynode", @node, @container) @parser.parse_elements(@container) end it "should not document node parsed in an other file" do @node.stubs(:file).returns("/not/same/path/file.pp") @resource_type_collection.add_node(@node) @parser.expects(:document_node).with("mynode", @node, @container).never @parser.parse_elements(@container) end end describe "when documenting definition" do before(:each) do @define = stub_everything 'define', :arguments => [], :doc => "mydoc", :file => "file", :line => 42 @class = stub_everything 'class' @parser.stubs(:get_class_or_module).returns([@class, "mydef"]) end it "should register a RDoc method to the current container" do @class.expects(:add_method).with { |m| m.name == "mydef"} @parser.document_define("mydef", @define, @class) end it "should attach the documentation to this method" do @class.expects(:add_method).with { |m| m.comment = "mydoc" } @parser.document_define("mydef", @define, @class) end it "should produce a better error message on unhandled exception" do @class.expects(:add_method).raises(ArgumentError) lambda { @parser.document_define("mydef", @define, @class) }.should raise_error(Puppet::ParseError, /in file at line 42/) end it "should convert all definition parameter to string" do arg = stub 'arg' val = stub 'val' @define.stubs(:arguments).returns({arg => val}) arg.expects(:to_s).returns("arg") val.expects(:to_s).returns("val") @parser.document_define("mydef", @define, @class) end end describe "when documenting nodes" do before :each do @code = stub_everything 'code' @node = stub_everything 'node', :doc => "mydoc", :parent => "parent", :code => @code, :file => "file", :line => 42 @rdoc_node = stub_everything 'rdocnode' @class = stub_everything 'class' @class.stubs(:add_node).returns(@rdoc_node) end it "should add a node to the current container" do @class.expects(:add_node).with("mynode", "parent").returns(@rdoc_node) @parser.document_node("mynode", @node, @class) end it "should associate the node documentation to the rdoc node" do @rdoc_node.expects(:comment=).with("mydoc") @parser.document_node("mynode", @node, @class) end it "should scan for include and require" do @parser.expects(:scan_for_include_or_require).with(@rdoc_node, @code) @parser.document_node("mynode", @node, @class) end it "should scan for variable definition" do @parser.expects(:scan_for_vardef).with(@rdoc_node, @code) @parser.document_node("mynode", @node, @class) end it "should scan for resources if needed" do Puppet.settings.stubs(:[]).with(:document_all).returns(true) @parser.expects(:scan_for_resource).with(@rdoc_node, @code) @parser.document_node("mynode", @node, @class) end it "should produce a better error message on unhandled exception" do @class.stubs(:add_node).raises(ArgumentError) lambda { @parser.document_node("mynode", @node, @class) }.should raise_error(Puppet::ParseError, /in file at line 42/) end end describe "when documenting classes" do before :each do @code = stub_everything 'code' @class = stub_everything 'class', :doc => "mydoc", :parent => "parent", :code => @code, :file => "file", :line => 42 @rdoc_class = stub_everything 'rdoc-class' @module = stub_everything 'class' @module.stubs(:add_class).returns(@rdoc_class) @parser.stubs(:get_class_or_module).returns([@module, "myclass"]) end it "should add a class to the current container" do @module.expects(:add_class).with(RDoc::PuppetClass, "myclass", "parent").returns(@rdoc_class) @parser.document_class("mynode", @class, @module) end it "should set the superclass" do @rdoc_class.expects(:superclass=).with("parent") @parser.document_class("mynode", @class, @module) end it "should associate the node documentation to the rdoc class" do @rdoc_class.expects(:comment=).with("mydoc") @parser.document_class("mynode", @class, @module) end it "should scan for include and require" do @parser.expects(:scan_for_include_or_require).with(@rdoc_class, @code) @parser.document_class("mynode", @class, @module) end it "should scan for resources if needed" do Puppet.settings.stubs(:[]).with(:document_all).returns(true) @parser.expects(:scan_for_resource).with(@rdoc_class, @code) @parser.document_class("mynode", @class, @module) end it "should produce a better error message on unhandled exception" do @module.stubs(:add_class).raises(ArgumentError) lambda { @parser.document_class("mynode", @class, @module) }.should raise_error(Puppet::ParseError, /in file at line 42/) end end describe "when scanning for includes and requires" do def create_stmt(name) stmt_value = stub "#{name}_value", :to_s => "myclass" Puppet::Parser::AST::Function.new( :name => name, :arguments => [stmt_value], :doc => 'mydoc' ) end before(:each) do @class = stub_everything 'class' @code = stub_everything 'code' @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true) end it "should also scan mono-instruction code" do @class.expects(:add_include).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" } @parser.scan_for_include_or_require(@class, create_stmt("include")) end it "should register recursively includes to the current container" do @code.stubs(:children).returns([ create_stmt("include") ]) @class.expects(:add_include)#.with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" } @parser.scan_for_include_or_require(@class, [@code]) end it "should register requires to the current container" do @code.stubs(:children).returns([ create_stmt("require") ]) @class.expects(:add_require).with { |i| i.is_a?(RDoc::Include) and i.name == "myclass" and i.comment == "mydoc" } @parser.scan_for_include_or_require(@class, [@code]) end end describe "when scanning for realized virtual resources" do def create_stmt stmt_value = stub "resource_ref", :to_s => "File[\"/tmp/a\"]" Puppet::Parser::AST::Function.new( :name => 'realize', :arguments => [stmt_value], :doc => 'mydoc' ) end before(:each) do @class = stub_everything 'class' @code = stub_everything 'code' @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true) end it "should also scan mono-instruction code" do @class.expects(:add_realize).with { |i| i.is_a?(RDoc::Include) and i.name == "File[\"/tmp/a\"]" and i.comment == "mydoc" } @parser.scan_for_realize(@class,create_stmt) end it "should register recursively includes to the current container" do @code.stubs(:children).returns([ create_stmt ]) @class.expects(:add_realize).with { |i| i.is_a?(RDoc::Include) and i.name == "File[\"/tmp/a\"]" and i.comment == "mydoc" } @parser.scan_for_realize(@class, [@code]) end end describe "when scanning for variable definition" do before :each do @class = stub_everything 'class' @stmt = stub_everything 'stmt', :name => "myvar", :value => "myvalue", :doc => "mydoc" @stmt.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(false) @stmt.stubs(:is_a?).with(Puppet::Parser::AST::VarDef).returns(true) @code = stub_everything 'code' @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true) end it "should recursively register variables to the current container" do @code.stubs(:children).returns([ @stmt ]) @class.expects(:add_constant).with { |i| i.is_a?(RDoc::Constant) and i.name == "myvar" and i.comment == "mydoc" } @parser.scan_for_vardef(@class, [ @code ]) end it "should also scan mono-instruction code" do @class.expects(:add_constant).with { |i| i.is_a?(RDoc::Constant) and i.name == "myvar" and i.comment == "mydoc" } @parser.scan_for_vardef(@class, @stmt) end end describe "when scanning for resources" do before :each do @class = stub_everything 'class' @stmt = Puppet::Parser::AST::Resource.new( :type => "File", :instances => Puppet::Parser::AST::ASTArray.new(:children => [ Puppet::Parser::AST::ResourceInstance.new( :title => Puppet::Parser::AST::Name.new(:value => "myfile"), :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) ) ]), :doc => 'mydoc' ) @code = stub_everything 'code' @code.stubs(:is_a?).with(Puppet::Parser::AST::ASTArray).returns(true) end it "should register a PuppetResource to the current container" do @code.stubs(:children).returns([ @stmt ]) @class.expects(:add_resource).with { |i| i.is_a?(RDoc::PuppetResource) and i.title == "myfile" and i.comment == "mydoc" } @parser.scan_for_resource(@class, [ @code ]) end it "should also scan mono-instruction code" do @class.expects(:add_resource).with { |i| i.is_a?(RDoc::PuppetResource) and i.title == "myfile" and i.comment == "mydoc" } @parser.scan_for_resource(@class, @stmt) end end describe "when parsing plugins" do before :each do @container = stub 'container' end it "should delegate parsing custom facts to parse_facts" do @parser = RDoc::Parser.new(@top_level, "module/manifests/lib/puppet/facter/test.rb", nil, Options.instance, RDoc::Stats.new) @parser.expects(:parse_fact).with(@container) @parser.parse_plugins(@container) end it "should delegate parsing plugins to parse_plugins" do @parser = RDoc::Parser.new(@top_level, "module/manifests/lib/puppet/functions/test.rb", nil, Options.instance, RDoc::Stats.new) @parser.expects(:parse_puppet_plugin).with(@container) @parser.parse_plugins(@container) end end describe "when parsing plugins" do before :each do @container = stub_everything 'container' end it "should add custom functions to the container" do File.stubs(:open).yields("# documentation module Puppet::Parser::Functions newfunction(:myfunc, :type => :rvalue) do |args| File.dirname(args[0]) end end".split("\n")) @container.expects(:add_plugin).with do |plugin| plugin.comment == "documentation\n" #and plugin.name == "myfunc" end @parser.parse_puppet_plugin(@container) end it "should add custom types to the container" do File.stubs(:open).yields("# documentation Puppet::Type.newtype(:mytype) do end".split("\n")) @container.expects(:add_plugin).with do |plugin| plugin.comment == "documentation\n" #and plugin.name == "mytype" end @parser.parse_puppet_plugin(@container) end end describe "when parsing facts" do before :each do @container = stub_everything 'container' File.stubs(:open).yields(["# documentation", "Facter.add('myfact') do", "confine :kernel => :linux", "end"]) end it "should add facts to the container" do @container.expects(:add_fact).with do |fact| fact.comment == "documentation\n" and fact.name == "myfact" end @parser.parse_fact(@container) end it "should add confine to the parsed facts" do ourfact = nil @container.expects(:add_fact).with do |fact| ourfact = fact true end @parser.parse_fact(@container) ourfact.confine.should == { :type => "kernel", :value => ":linux" } end end end diff --git a/spec/unit/util/rdoc_spec.rb b/spec/unit/util/rdoc_spec.rb index deae4ef2c..93e5d0ee1 100755 --- a/spec/unit/util/rdoc_spec.rb +++ b/spec/unit/util/rdoc_spec.rb @@ -1,147 +1,152 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/rdoc' require 'rdoc/rdoc' describe Puppet::Util::RDoc do + it "should fail with a clear error without RDoc 1.*" do + Puppet.features.stubs(:rdoc1?).returns(false) - describe "when generating RDoc HTML documentation", :'fails_on_ruby_1.9.2' => true do + expect { Puppet::Util::RDoc.rdoc("output", []) }. + should raise_error(/the version of RDoc .* is not supported/) + end + + describe "when generating RDoc HTML documentation", :if => Puppet.features.rdoc1? do before :each do @rdoc = stub_everything 'rdoc' RDoc::RDoc.stubs(:new).returns(@rdoc) end it "should tell the parser to ignore import" do Puppet.expects(:[]=).with(:ignoreimport, true) - Puppet::Util::RDoc.rdoc("output", []) end it "should install the Puppet HTML Generator into RDoc generators" do Puppet::Util::RDoc.rdoc("output", []) RDoc::RDoc::GENERATORS["puppet"].file_name.should == "puppet/util/rdoc/generators/puppet_generator.rb" end it "should tell RDoc to generate documentation using the Puppet generator" do @rdoc.expects(:document).with { |args| args.include?("--fmt") and args.include?("puppet") } Puppet::Util::RDoc.rdoc("output", []) end it "should tell RDoc to be quiet" do @rdoc.expects(:document).with { |args| args.include?("--quiet") } Puppet::Util::RDoc.rdoc("output", []) end it "should pass charset to RDoc" do @rdoc.expects(:document).with { |args| args.include?("--charset") and args.include?("utf-8") } Puppet::Util::RDoc.rdoc("output", [], "utf-8") end it "should tell RDoc to force updates of indices when RDoc supports it" do Options::OptionList.stubs(:options).returns([["--force-update", "-U", 0 ]]) @rdoc.expects(:document).with { |args| args.include?("--force-update") } Puppet::Util::RDoc.rdoc("output", []) end it "should not tell RDoc to force updates of indices when RDoc doesn't support it" do Options::OptionList.stubs(:options).returns([]) @rdoc.expects(:document).never.with { |args| args.include?("--force-update") } Puppet::Util::RDoc.rdoc("output", []) end it "should tell RDoc to use the given outputdir" do @rdoc.expects(:document).with { |args| args.include?("--op") and args.include?("myoutputdir") } Puppet::Util::RDoc.rdoc("myoutputdir", []) end it "should tell RDoc to exclude .pp files under any modules//files section" do @rdoc.expects(:document).with { |args| args.include?("--exclude") and args.include?("/modules/[^/]*/files/.*\.pp$") } Puppet::Util::RDoc.rdoc("myoutputdir", []) end it "should give all the source directories to RDoc" do @rdoc.expects(:document).with { |args| args.include?("sourcedir") } Puppet::Util::RDoc.rdoc("output", ["sourcedir"]) end end describe "when running a manifest documentation" do it "should tell the parser to ignore import" do Puppet.expects(:[]=).with(:ignoreimport, true) Puppet::Util::RDoc.manifestdoc([]) end it "should use a parser with the correct environment" do FileTest.stubs(:file?).returns(true) Puppet::Util::RDoc.stubs(:output) parser = stub_everything Puppet::Parser::Parser.stubs(:new).with{ |env| env.is_a?(Puppet::Node::Environment) }.returns(parser) parser.expects(:file=).with("file") parser.expects(:parse) Puppet::Util::RDoc.manifestdoc(["file"]) end it "should puppet parse all given files" do FileTest.stubs(:file?).returns(true) Puppet::Util::RDoc.stubs(:output) parser = stub_everything Puppet::Parser::Parser.stubs(:new).returns(parser) parser.expects(:file=).with("file") parser.expects(:parse) Puppet::Util::RDoc.manifestdoc(["file"]) end it "should call output for each parsed file" do FileTest.stubs(:file?).returns(true) ast = stub_everything parser = stub_everything Puppet::Parser::Parser.stubs(:new).returns(parser) parser.stubs(:parse).returns(ast) Puppet::Util::RDoc.expects(:output).with("file", ast) Puppet::Util::RDoc.manifestdoc(["file"]) end describe "when outputing documentation" do it "should output doc for ast classes, nodes and definitions in order of increasing line number" do byline = sequence('documentation outputs in line order') Puppet::Util::RDoc.expects(:puts).with("im a class\n").in_sequence(byline) Puppet::Util::RDoc.expects(:puts).with("im a node\n").in_sequence(byline) Puppet::Util::RDoc.expects(:puts).with("im a define\n").in_sequence(byline) # any other output must fail Puppet::Util::RDoc.manifestdoc([my_fixture('basic.pp')]) end it "should output resource documentation if needed" do pending "#6634 being fixed" Puppet.settings[:document_all] = true byline = sequence('documentation outputs in line order') Puppet::Util::RDoc.expects(:puts).with("im a class\n").in_sequence(byline) Puppet::Util::RDoc.expects(:puts).with("im a node\n").in_sequence(byline) Puppet::Util::RDoc.expects(:puts).with("im a define\n").in_sequence(byline) Puppet::Util::RDoc.expects(:puts).with("im a resource\n").in_sequence(byline) # any other output must fail Puppet::Util::RDoc.manifestdoc([my_fixture('basic.pp')]) end end end end diff --git a/spec/unit/util/storage_spec.rb b/spec/unit/util/storage_spec.rb index 575ad1ef3..cbdaa4389 100755 --- a/spec/unit/util/storage_spec.rb +++ b/spec/unit/util/storage_spec.rb @@ -1,233 +1,217 @@ #!/usr/bin/env rspec require 'spec_helper' require 'yaml' require 'puppet/util/storage' describe Puppet::Util::Storage do include PuppetSpec::Files before(:all) do @basepath = make_absolute("/somepath") Puppet[:statedir] = tmpdir("statedir") end after(:all) do Puppet.settings.clear end before(:each) do Puppet::Util::Storage.clear end describe "when caching a symbol" do it "should return an empty hash" do Puppet::Util::Storage.cache(:yayness).should == {} Puppet::Util::Storage.cache(:more_yayness).should == {} end it "should add the symbol to its internal state" do Puppet::Util::Storage.cache(:yayness) Puppet::Util::Storage.state.should == {:yayness=>{}} end it "should not clobber existing state when caching additional objects" do Puppet::Util::Storage.cache(:yayness) Puppet::Util::Storage.state.should == {:yayness=>{}} Puppet::Util::Storage.cache(:bubblyness) Puppet::Util::Storage.state.should == {:yayness=>{},:bubblyness=>{}} end end describe "when caching a Puppet::Type" do before(:all) do @file_test = Puppet::Type.type(:file).new(:name => @basepath+"/yayness", :check => %w{checksum type}) @exec_test = Puppet::Type.type(:exec).new(:name => @basepath+"/bin/ls /yayness") end it "should return an empty hash" do Puppet::Util::Storage.cache(@file_test).should == {} Puppet::Util::Storage.cache(@exec_test).should == {} end it "should add the resource ref to its internal state" do Puppet::Util::Storage.state.should == {} Puppet::Util::Storage.cache(@file_test) Puppet::Util::Storage.state.should == {"File[#{@basepath}/yayness]"=>{}} Puppet::Util::Storage.cache(@exec_test) Puppet::Util::Storage.state.should == {"File[#{@basepath}/yayness]"=>{}, "Exec[#{@basepath}/bin/ls /yayness]"=>{}} end end describe "when caching something other than a resource or symbol" do it "should cache by converting to a string" do data = Puppet::Util::Storage.cache(42) data[:yay] = true Puppet::Util::Storage.cache("42")[:yay].should be_true end end it "should clear its internal state when clear() is called" do Puppet::Util::Storage.cache(:yayness) Puppet::Util::Storage.state.should == {:yayness=>{}} Puppet::Util::Storage.clear Puppet::Util::Storage.state.should == {} end describe "when loading from the state file" do before do Puppet.settings.stubs(:use).returns(true) end describe "when the state file/directory does not exist" do before(:each) do transient = Tempfile.new('storage_test') @path = transient.path() transient.close!() end it "should not fail to load()" do FileTest.exists?(@path).should be_false Puppet[:statedir] = @path proc { Puppet::Util::Storage.load }.should_not raise_error Puppet[:statefile] = @path proc { Puppet::Util::Storage.load }.should_not raise_error end it "should not lose its internal state when load() is called" do FileTest.exists?(@path).should be_false Puppet::Util::Storage.cache(:yayness) Puppet::Util::Storage.state.should == {:yayness=>{}} Puppet[:statefile] = @path proc { Puppet::Util::Storage.load }.should_not raise_error Puppet::Util::Storage.state.should == {:yayness=>{}} end end describe "when the state file/directory exists" do before(:each) do @state_file = Tempfile.new('storage_test') @saved_statefile = Puppet[:statefile] Puppet[:statefile] = @state_file.path end it "should overwrite its internal state if load() is called" do # Should the state be overwritten even if Puppet[:statefile] is not valid YAML? Puppet::Util::Storage.cache(:yayness) Puppet::Util::Storage.state.should == {:yayness=>{}} proc { Puppet::Util::Storage.load }.should_not raise_error Puppet::Util::Storage.state.should == {} end it "should restore its internal state if the state file contains valid YAML" do test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}} YAML.expects(:load).returns(test_yaml) proc { Puppet::Util::Storage.load }.should_not raise_error Puppet::Util::Storage.state.should == test_yaml end it "should initialize with a clear internal state if the state file does not contain valid YAML" do @state_file.write(:booness) @state_file.flush proc { Puppet::Util::Storage.load }.should_not raise_error Puppet::Util::Storage.state.should == {} end it "should raise an error if the state file does not contain valid YAML and cannot be renamed" do @state_file.write(:booness) @state_file.flush YAML.expects(:load).raises(Puppet::Error) File.expects(:rename).raises(SystemCallError) proc { Puppet::Util::Storage.load }.should raise_error end it "should attempt to rename the state file if the file is corrupted" do # We fake corruption by causing YAML.load to raise an exception YAML.expects(:load).raises(Puppet::Error) File.expects(:rename).at_least_once proc { Puppet::Util::Storage.load }.should_not raise_error end it "should fail gracefully on load() if the state file is not a regular file" do @state_file.close!() Dir.mkdir(Puppet[:statefile]) proc { Puppet::Util::Storage.load }.should_not raise_error Dir.rmdir(Puppet[:statefile]) end - it "should fail gracefully on load() if it cannot get a read lock on the state file" do - Puppet::Util::FileLocking.expects(:readlock).yields(false) - test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}} - YAML.expects(:load).returns(test_yaml) - - proc { Puppet::Util::Storage.load }.should_not raise_error - Puppet::Util::Storage.state.should == test_yaml - end - after(:each) do @state_file.close!() Puppet[:statefile] = @saved_statefile end end end describe "when storing to the state file" do before(:each) do @state_file = Tempfile.new('storage_test') @saved_statefile = Puppet[:statefile] Puppet[:statefile] = @state_file.path end it "should create the state file if it does not exist" do @state_file.close!() FileTest.exists?(Puppet[:statefile]).should be_false Puppet::Util::Storage.cache(:yayness) proc { Puppet::Util::Storage.store }.should_not raise_error FileTest.exists?(Puppet[:statefile]).should be_true end it "should raise an exception if the state file is not a regular file" do @state_file.close!() Dir.mkdir(Puppet[:statefile]) Puppet::Util::Storage.cache(:yayness) proc { Puppet::Util::Storage.store }.should raise_error Dir.rmdir(Puppet[:statefile]) end - it "should raise an exception if it cannot get a write lock on the state file" do - Puppet::Util::FileLocking.expects(:writelock).yields(false) - Puppet::Util::Storage.cache(:yayness) - - proc { Puppet::Util::Storage.store }.should raise_error - end - it "should load() the same information that it store()s" do Puppet::Util::Storage.cache(:yayness) Puppet::Util::Storage.state.should == {:yayness=>{}} proc { Puppet::Util::Storage.store }.should_not raise_error Puppet::Util::Storage.clear Puppet::Util::Storage.state.should == {} proc { Puppet::Util::Storage.load }.should_not raise_error Puppet::Util::Storage.state.should == {:yayness=>{}} end after(:each) do @state_file.close!() Puppet[:statefile] = @saved_statefile end end end diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb index 858ae6044..ea562a205 100755 --- a/spec/unit/util/zaml_spec.rb +++ b/spec/unit/util/zaml_spec.rb @@ -1,99 +1,123 @@ #!/usr/bin/env rspec # encoding: UTF-8 # # The above encoding line is a magic comment to set the default source encoding # of this file for the Ruby interpreter. It must be on the first or second # line of the file if an interpreter is in use. In Ruby 1.9 and later, the # source encoding determines the encoding of String and Regexp objects created # from this source file. This explicit encoding is important becuase otherwise # Ruby will pick an encoding based on LANG or LC_CTYPE environment variables. # These may be different from site to site so it's important for us to # establish a consistent behavior. For more information on M17n please see: # http://links.puppetlabs.com/understanding_m17n require 'spec_helper' require 'puppet/util/monkey_patches' describe "Pure ruby yaml implementation" do { 7 => "--- 7", 3.14159 => "--- 3.14159", 'test' => "--- test", [] => "--- []", :symbol => "--- !ruby/sym symbol", {:a => "A"} => "--- \n !ruby/sym a: A", {:a => "x\ny"} => "--- \n !ruby/sym a: |-\n x\n y" }.each { |o,y| it "should convert the #{o.class} #{o.inspect} to yaml" do o.to_yaml.should == y end it "should produce yaml for the #{o.class} #{o.inspect} that can be reconstituted" do YAML.load(o.to_yaml).should == o end } # # Can't test for equality on raw objects { Object.new => "--- !ruby/object {}", [Object.new] => "--- \n - !ruby/object {}", {Object.new => Object.new} => "--- \n ? !ruby/object {}\n : !ruby/object {}" }.each { |o,y| it "should convert the #{o.class} #{o.inspect} to yaml" do o.to_yaml.should == y end it "should produce yaml for the #{o.class} #{o.inspect} that can be reconstituted" do lambda { YAML.load(o.to_yaml) }.should_not raise_error end } it "should emit proper labels and backreferences for common objects" do # Note: this test makes assumptions about the names ZAML chooses # for labels. x = [1, 2] y = [3, 4] z = [x, y, x, y] z.to_yaml.should == "--- \n - &id001\n - 1\n - 2\n - &id002\n - 3\n - 4\n - *id001\n - *id002" z2 = YAML.load(z.to_yaml) z2.should == z z2[0].should equal(z2[2]) z2[1].should equal(z2[3]) end it "should emit proper labels and backreferences for recursive objects" do x = [1, 2] x << x x.to_yaml.should == "--- &id001\n \n - 1\n - 2\n - *id001" x2 = YAML.load(x.to_yaml) x2.should be_a(Array) x2.length.should == 3 x2[0].should == 1 x2[1].should == 2 x2[2].should equal(x2) end end # Note, many of these tests will pass on Ruby 1.8 but fail on 1.9 if the patch # fix is not applied to Puppet or there's a regression. These version # dependant failures are intentional since the string encoding behavior changed # significantly in 1.9. describe "UTF-8 encoded String#to_yaml (Bug #11246)" do # JJM All of these snowmen are different representations of the same # UTF-8 encoded string. let(:snowman) { 'Snowman: [☃]' } let(:snowman_escaped) { "Snowman: [\xE2\x98\x83]" } describe "UTF-8 String Literal" do subject { snowman } it "should serialize to YAML" do subject.to_yaml end it "should serialize and deserialize to the same thing" do YAML.load(subject.to_yaml).should == subject end it "should serialize and deserialize to a String compatible with a UTF-8 encoded Regexp" do YAML.load(subject.to_yaml).should =~ /☃/u end end end + +describe "binary data" do + subject { "M\xC0\xDF\xE5tt\xF6" } + + it "should not explode encoding binary data" do + expect { subject.to_yaml }.not_to raise_error + end + + it "should mark the binary data as binary" do + subject.to_yaml.should =~ /!binary/ + end + + it "should round-trip the data" do + yaml = subject.to_yaml + read = YAML.load(yaml) + + if read.respond_to? :force_encoding + read.force_encoding('binary') + subject.force_encoding('binary') + end + + read.should == subject + end +end diff --git a/spec/unit/util_spec.rb b/spec/unit/util_spec.rb index 4216f15ea..704e2851c 100755 --- a/spec/unit/util_spec.rb +++ b/spec/unit/util_spec.rb @@ -1,445 +1,435 @@ #!/usr/bin/env ruby require 'spec_helper' describe Puppet::Util do include PuppetSpec::Files if Puppet.features.microsoft_windows? def set_mode(mode, file) Puppet::Util::Windows::Security.set_mode(mode, file) end def get_mode(file) Puppet::Util::Windows::Security.get_mode(file) & 07777 end else def set_mode(mode, file) File.chmod(mode, file) end def get_mode(file) File.lstat(file).mode & 07777 end end describe "#withenv" do before :each do @original_path = ENV["PATH"] @new_env = {:PATH => "/some/bogus/path"} end it "should change environment variables within the block then reset environment variables to their original values" do Puppet::Util.withenv @new_env do ENV["PATH"].should == "/some/bogus/path" end ENV["PATH"].should == @original_path end it "should reset environment variables to their original values even if the block fails" do begin Puppet::Util.withenv @new_env do ENV["PATH"].should == "/some/bogus/path" raise "This is a failure" end rescue end ENV["PATH"].should == @original_path end it "should reset environment variables even when they are set twice" do # Setting Path & Environment parameters in Exec type can cause weirdness @new_env["PATH"] = "/someother/bogus/path" Puppet::Util.withenv @new_env do # When assigning duplicate keys, can't guarantee order of evaluation ENV["PATH"].should =~ /\/some.*\/bogus\/path/ end ENV["PATH"].should == @original_path end it "should remove any new environment variables after the block ends" do @new_env[:FOO] = "bar" Puppet::Util.withenv @new_env do ENV["FOO"].should == "bar" end ENV["FOO"].should == nil end end describe "#absolute_path?" do it "should default to the platform of the local system" do Puppet.features.stubs(:posix?).returns(true) Puppet.features.stubs(:microsoft_windows?).returns(false) Puppet::Util.should be_absolute_path('/foo') Puppet::Util.should_not be_absolute_path('C:/foo') Puppet.features.stubs(:posix?).returns(false) Puppet.features.stubs(:microsoft_windows?).returns(true) Puppet::Util.should be_absolute_path('C:/foo') Puppet::Util.should_not be_absolute_path('/foo') end describe "when using platform :posix" do %w[/ /foo /foo/../bar //foo //Server/Foo/Bar //?/C:/foo/bar /\Server/Foo /foo//bar/baz].each do |path| it "should return true for #{path}" do Puppet::Util.should be_absolute_path(path, :posix) end end %w[. ./foo \foo C:/foo \\Server\Foo\Bar \\?\C:\foo\bar \/?/foo\bar \/Server/foo foo//bar/baz].each do |path| it "should return false for #{path}" do Puppet::Util.should_not be_absolute_path(path, :posix) end end end describe "when using platform :windows" do %w[C:/foo C:\foo \\\\Server\Foo\Bar \\\\?\C:\foo\bar //Server/Foo/Bar //?/C:/foo/bar /\?\C:/foo\bar \/Server\Foo/Bar c:/foo//bar//baz].each do |path| it "should return true for #{path}" do Puppet::Util.should be_absolute_path(path, :windows) end end %w[/ . ./foo \foo /foo /foo/../bar //foo C:foo/bar foo//bar/baz].each do |path| it "should return false for #{path}" do Puppet::Util.should_not be_absolute_path(path, :windows) end end end end describe "#path_to_uri" do %w[. .. foo foo/bar foo/../bar].each do |path| it "should reject relative path: #{path}" do lambda { Puppet::Util.path_to_uri(path) }.should raise_error(Puppet::Error) end end it "should perform URI escaping" do Puppet::Util.path_to_uri("/foo bar").path.should == "/foo%20bar" end describe "when using platform :posix" do before :each do Puppet.features.stubs(:posix).returns true Puppet.features.stubs(:microsoft_windows?).returns false end %w[/ /foo /foo/../bar].each do |path| it "should convert #{path} to URI" do Puppet::Util.path_to_uri(path).path.should == path end end end describe "when using platform :windows" do before :each do Puppet.features.stubs(:posix).returns false Puppet.features.stubs(:microsoft_windows?).returns true end it "should normalize backslashes" do Puppet::Util.path_to_uri('c:\\foo\\bar\\baz').path.should == '/' + 'c:/foo/bar/baz' end %w[C:/ C:/foo/bar].each do |path| it "should convert #{path} to absolute URI" do Puppet::Util.path_to_uri(path).path.should == '/' + path end end %w[share C$].each do |path| it "should convert UNC #{path} to absolute URI" do uri = Puppet::Util.path_to_uri("\\\\server\\#{path}") uri.host.should == 'server' uri.path.should == '/' + path end end end end describe ".uri_to_path" do require 'uri' it "should strip host component" do Puppet::Util.uri_to_path(URI.parse('http://foo/bar')).should == '/bar' end it "should accept puppet URLs" do Puppet::Util.uri_to_path(URI.parse('puppet:///modules/foo')).should == '/modules/foo' end it "should return unencoded path" do Puppet::Util.uri_to_path(URI.parse('http://foo/bar%20baz')).should == '/bar baz' end it "should be nil-safe" do Puppet::Util.uri_to_path(nil).should be_nil end describe "when using platform :posix",:if => Puppet.features.posix? do it "should accept root" do Puppet::Util.uri_to_path(URI.parse('file:/')).should == '/' end it "should accept single slash" do Puppet::Util.uri_to_path(URI.parse('file:/foo/bar')).should == '/foo/bar' end it "should accept triple slashes" do Puppet::Util.uri_to_path(URI.parse('file:///foo/bar')).should == '/foo/bar' end end describe "when using platform :windows", :if => Puppet.features.microsoft_windows? do it "should accept root" do Puppet::Util.uri_to_path(URI.parse('file:/C:/')).should == 'C:/' end it "should accept single slash" do Puppet::Util.uri_to_path(URI.parse('file:/C:/foo/bar')).should == 'C:/foo/bar' end it "should accept triple slashes" do Puppet::Util.uri_to_path(URI.parse('file:///C:/foo/bar')).should == 'C:/foo/bar' end it "should accept file scheme with double slashes as a UNC path" do Puppet::Util.uri_to_path(URI.parse('file://host/share/file')).should == '//host/share/file' end end end describe "#which" do let(:base) { File.expand_path('/bin') } let(:path) { File.join(base, 'foo') } before :each do FileTest.stubs(:file?).returns false FileTest.stubs(:file?).with(path).returns true FileTest.stubs(:executable?).returns false FileTest.stubs(:executable?).with(path).returns true end it "should accept absolute paths" do Puppet::Util.which(path).should == path end it "should return nil if no executable found" do Puppet::Util.which('doesnotexist').should be_nil end it "should warn if the user's HOME is not set but their PATH contains a ~" do env_path = %w[~/bin /usr/bin /bin].join(File::PATH_SEPARATOR) Puppet::Util.withenv({:HOME => nil, :PATH => env_path}) do Puppet::Util::Warnings.expects(:warnonce).once Puppet::Util.which('foo') end end it "should reject directories" do Puppet::Util.which(base).should be_nil end describe "on POSIX systems" do before :each do Puppet.features.stubs(:posix?).returns true Puppet.features.stubs(:microsoft_windows?).returns false end it "should walk the search PATH returning the first executable" do ENV.stubs(:[]).with('PATH').returns(File.expand_path('/bin')) Puppet::Util.which('foo').should == path end end describe "on Windows systems" do let(:path) { File.expand_path(File.join(base, 'foo.CMD')) } before :each do Puppet.features.stubs(:posix?).returns false Puppet.features.stubs(:microsoft_windows?).returns true end describe "when a file extension is specified" do it "should walk each directory in PATH ignoring PATHEXT" do ENV.stubs(:[]).with('PATH').returns(%w[/bar /bin].map{|dir| File.expand_path(dir)}.join(File::PATH_SEPARATOR)) FileTest.expects(:file?).with(File.join(File.expand_path('/bar'), 'foo.CMD')).returns false ENV.expects(:[]).with('PATHEXT').never Puppet::Util.which('foo.CMD').should == path end end describe "when a file extension is not specified" do it "should walk each extension in PATHEXT until an executable is found" do bar = File.expand_path('/bar') ENV.stubs(:[]).with('PATH').returns("#{bar}#{File::PATH_SEPARATOR}#{base}") ENV.stubs(:[]).with('PATHEXT').returns(".EXE#{File::PATH_SEPARATOR}.CMD") exts = sequence('extensions') FileTest.expects(:file?).in_sequence(exts).with(File.join(bar, 'foo.EXE')).returns false FileTest.expects(:file?).in_sequence(exts).with(File.join(bar, 'foo.CMD')).returns false FileTest.expects(:file?).in_sequence(exts).with(File.join(base, 'foo.EXE')).returns false FileTest.expects(:file?).in_sequence(exts).with(path).returns true Puppet::Util.which('foo').should == path end it "should walk the default extension path if the environment variable is not defined" do ENV.stubs(:[]).with('PATH').returns(base) ENV.stubs(:[]).with('PATHEXT').returns(nil) exts = sequence('extensions') %w[.COM .EXE .BAT].each do |ext| FileTest.expects(:file?).in_sequence(exts).with(File.join(base, "foo#{ext}")).returns false end FileTest.expects(:file?).in_sequence(exts).with(path).returns true Puppet::Util.which('foo').should == path end it "should fall back if no extension matches" do ENV.stubs(:[]).with('PATH').returns(base) ENV.stubs(:[]).with('PATHEXT').returns(".EXE") FileTest.stubs(:file?).with(File.join(base, 'foo.EXE')).returns false FileTest.stubs(:file?).with(File.join(base, 'foo')).returns true FileTest.stubs(:executable?).with(File.join(base, 'foo')).returns true Puppet::Util.which('foo').should == File.join(base, 'foo') end end end end describe "#binread" do let(:contents) { "foo\r\nbar" } it "should preserve line endings" do path = tmpfile('util_binread') File.open(path, 'wb') { |f| f.print contents } Puppet::Util.binread(path).should == contents end it "should raise an error if the file doesn't exist" do expect { Puppet::Util.binread('/path/does/not/exist') }.to raise_error(Errno::ENOENT) end end context "#replace_file" do - describe "on POSIX platforms", :if => Puppet.features.posix? do - subject { Puppet::Util } - it { should respond_to :replace_file } + subject { Puppet::Util } + it { should respond_to :replace_file } - let :target do - target = Tempfile.new("puppet-util-replace-file") - target.puts("hello, world") - target.flush # make sure content is on disk. - target.fsync rescue nil - target.close - target - end - - it "should fail if no block is given" do - expect { subject.replace_file(target.path, 0600) }.to raise_error /block/ - end + let :target do + target = Tempfile.new("puppet-util-replace-file") + target.puts("hello, world") + target.flush # make sure content is on disk. + target.fsync rescue nil + target.close + target + end - it "should replace a file when invoked" do - # Check that our file has the expected content. - File.read(target.path).should == "hello, world\n" + it "should fail if no block is given" do + expect { subject.replace_file(target.path, 0600) }.to raise_error /block/ + end - # Replace the file. - subject.replace_file(target.path, 0600) do |fh| - fh.puts "I am the passenger..." - end + it "should replace a file when invoked" do + # Check that our file has the expected content. + File.read(target.path).should == "hello, world\n" - # ...and check the replacement was complete. - File.read(target.path).should == "I am the passenger...\n" + # Replace the file. + subject.replace_file(target.path, 0600) do |fh| + fh.puts "I am the passenger..." end - [0555, 0600, 0660, 0700, 0770].each do |mode| - it "should copy 0#{mode.to_s(8)} permissions from the target file by default" do - set_mode(mode, target.path) - - get_mode(target.path).should == mode - - subject.replace_file(target.path, 0000) {|fh| fh.puts "bazam" } - - get_mode(target.path).should == mode - File.read(target.path).should == "bazam\n" - end - end + # ...and check the replacement was complete. + File.read(target.path).should == "I am the passenger...\n" + end - it "should copy the permissions of the source file before yielding" do - set_mode(0555, target.path) - inode = File.stat(target.path).ino unless Puppet.features.microsoft_windows? + [0555, 0600, 0660, 0700, 0770].each do |mode| + it "should copy 0#{mode.to_s(8)} permissions from the target file by default" do + set_mode(mode, target.path) - yielded = false - subject.replace_file(target.path, 0600) do |fh| - get_mode(fh.path).should == 0555 - yielded = true - end - yielded.should be_true + get_mode(target.path).should == mode - # We can't check inode on Windows - File.stat(target.path).ino.should_not == inode unless Puppet.features.microsoft_windows? + subject.replace_file(target.path, 0000) {|fh| fh.puts "bazam" } - get_mode(target.path).should == 0555 + get_mode(target.path).should == mode + File.read(target.path).should == "bazam\n" end + end - it "should use the default permissions if the source file doesn't exist" do - new_target = target.path + '.foo' - File.should_not be_exist(new_target) + it "should copy the permissions of the source file before yielding" do + set_mode(0555, target.path) + inode = File.stat(target.path).ino unless Puppet.features.microsoft_windows? - begin - subject.replace_file(new_target, 0555) {|fh| fh.puts "foo" } - get_mode(new_target).should == 0555 - ensure - File.unlink(new_target) if File.exists?(new_target) - end + yielded = false + subject.replace_file(target.path, 0600) do |fh| + get_mode(fh.path).should == 0555 + yielded = true end + yielded.should be_true - it "should not replace the file if an exception is thrown in the block" do - yielded = false - threw = false + # We can't check inode on Windows + File.stat(target.path).ino.should_not == inode unless Puppet.features.microsoft_windows? - begin - subject.replace_file(target.path, 0600) do |fh| - yielded = true - fh.puts "different content written, then..." - raise "...throw some random failure" - end - rescue Exception => e - if e.to_s =~ /some random failure/ - threw = true - else - raise - end - end + get_mode(target.path).should == 0555 + end - yielded.should be_true - threw.should be_true + it "should use the default permissions if the source file doesn't exist" do + new_target = target.path + '.foo' + File.should_not be_exist(new_target) - # ...and check the replacement was complete. - File.read(target.path).should == "hello, world\n" + begin + subject.replace_file(new_target, 0555) {|fh| fh.puts "foo" } + get_mode(new_target).should == 0555 + ensure + File.unlink(new_target) if File.exists?(new_target) end end - describe "on Windows platforms" do - it "should fail and complain" do - Puppet.features.stubs(:microsoft_windows?).returns true + it "should not replace the file if an exception is thrown in the block" do + yielded = false + threw = false - expect { Puppet::Util.replace_file("C:/foo", 0644) {} }.to raise_error(Puppet::DevError, "replace_file is non-functional on Windows") + begin + subject.replace_file(target.path, 0600) do |fh| + yielded = true + fh.puts "different content written, then..." + raise "...throw some random failure" + end + rescue Exception => e + if e.to_s =~ /some random failure/ + threw = true + else + raise + end end + + yielded.should be_true + threw.should be_true + + # ...and check the replacement was complete. + File.read(target.path).should == "hello, world\n" end end end diff --git a/test/README b/test/README deleted file mode 100644 index 82a749a69..000000000 --- a/test/README +++ /dev/null @@ -1,24 +0,0 @@ -$Id$ - -To run all tests, run: 'rake test'. To run an individual suite, run the file -directly. e.g. cd test/util; ./utiltest.rb - -You might need to run some tests as root. - -If you do not have rake installed: - gem install rake - -## The following information is possibly out of date? - -Tests are organized into a dual hierarchy: each subdirectory is -considered a test suite, and each file in the subdirectory is considered -a test case. You can use any test case as an example of how to write -more of them, but basically the only requirements are that they each have -their own class names, their names each match /tc_.+\.r/, and that they have -the following header: - -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $blinkbase = "../.." -end diff --git a/test/Rakefile b/test/Rakefile deleted file mode 100644 index 7cde050f6..000000000 --- a/test/Rakefile +++ /dev/null @@ -1,96 +0,0 @@ -# let Emacs know it's -*- ruby -*- -begin - require 'rake/testtask' -rescue LoadError - $stderr.puts "You must have 'rake' installed to use this file" - exit(1) -end - -require 'find' - -include Find -include FileTest - -$exclusions = %W(lib data) -$test_library_paths = %W(lib ../lib) - -$: << File.join(Dir.getwd, "lib") - -require 'rake/puppet_testtask' - -filemap = Hash.new { |hash, key| hash[key] = [] } - -allfiles = [] - -# First collect the entire file list. -find(".") do |f| - # Get rid of the leading ./ - f = f.sub(/^\.\//, '') - - file = File.basename(f) - dir = File.dirname(f) - - # Prune . directories and excluded dirs - if (file =~ /^\./ and f != ".") or $exclusions.include?(File.basename(file)) - prune - next - end - next if f == "." - next if dir == "." - - # If we're a ruby script, then add it to the list of files for that dir - if file =~ /\.rb$/ - allfiles << f - # Add it to all of the parent dirs, not just our own - parts = File.split(dir) - if parts[0] == "." - parts.shift - end - parts.each_with_index { |part, i| - path = File.join(parts[0..i]) - filemap[path] << f - } - end -end - -desc "Run the full test suite" -Rake::PuppetTestTask.new :test do |t| - t.libs += $test_library_paths - - # Add every file as a test file to run - t.test_files = allfiles - t.verbose = true -end - -task :default => :test - -# Now create a task for every directory -filemap.each do |dir, files| - ns = dir.gsub "/", ":" - - # First create a separate task for each file in the namespace. - namespace ns do - files.each do |file| - Rake::PuppetTestTask.new File.basename(file, '.rb').to_sym do |t| - t.libs += $test_library_paths + ['..'] - t.libs << '..' - t.test_files = [ file ] - t.verbose = true - end - end - end - - # Then create a task that matches the directory itself. - Rake::PuppetTestTask.new dir do |t| - t.libs += $test_library_paths - if ENV["TESTFILES"] - t.test_files = ENV["TESTFILES"].split(/\s+/) - else - t.test_files = files.sort - end - t.verbose = true - end - - # And alias it with a slash on the end - task(dir + "/" => dir) -end diff --git a/test/data/failers/badclassnoparam b/test/data/failers/badclassnoparam deleted file mode 100644 index a0397aacc..000000000 --- a/test/data/failers/badclassnoparam +++ /dev/null @@ -1,10 +0,0 @@ -class comp() { - file { "/etc/passwd": - mode => 644 - } -} - -# this argument is invalid, thus we should get a falure -comp { - fakearg => "yay" -} diff --git a/test/data/failers/badclassparam b/test/data/failers/badclassparam deleted file mode 100644 index 4c9ff6199..000000000 --- a/test/data/failers/badclassparam +++ /dev/null @@ -1,10 +0,0 @@ -class comp(arg1) { - file { "/etc/passwd": - mode => 644 - } -} - -# i've specified an arg but it's an invalid one -comp { - fakearg => "yay" -} diff --git a/test/data/failers/badcompnoparam b/test/data/failers/badcompnoparam deleted file mode 100644 index fd25c9445..000000000 --- a/test/data/failers/badcompnoparam +++ /dev/null @@ -1,9 +0,0 @@ -define comp() { - file { "/etc/passwd": - mode => 644 - } -} - -comp { - fakearg => "yay" -} diff --git a/test/data/failers/badcompparam b/test/data/failers/badcompparam deleted file mode 100644 index 346e64b25..000000000 --- a/test/data/failers/badcompparam +++ /dev/null @@ -1,9 +0,0 @@ -define comp($arg1) { - file { "/etc/passwd": - mode => 644 - } -} - -comp { - fakearg => "yay" -} diff --git a/test/data/failers/badtypeparam b/test/data/failers/badtypeparam deleted file mode 100644 index 4634f2052..000000000 --- a/test/data/failers/badtypeparam +++ /dev/null @@ -1,3 +0,0 @@ -file { "/etc/passwd": - fakeparam => 644 -} diff --git a/test/data/failers/noobjectrvalue b/test/data/failers/noobjectrvalue deleted file mode 100644 index ef6064740..000000000 --- a/test/data/failers/noobjectrvalue +++ /dev/null @@ -1 +0,0 @@ -$variable = file { "/etc/passwd": owner => root } diff --git a/test/data/providers/cron/crontab.allthree b/test/data/providers/cron/crontab.allthree deleted file mode 100644 index c1a61c30d..000000000 --- a/test/data/providers/cron/crontab.allthree +++ /dev/null @@ -1,17 +0,0 @@ ---- -- | - # comment 1 - # Puppet Name: name2 - env3=val - * * * * * command4 - # comment 5 - -- - :record_type: :comment - :line: "# comment 1" - - :command: command4 - :environment: - - env3=val - :name: name2 - :record_type: :crontab - - :record_type: :comment - :line: "# comment 5" diff --git a/test/data/providers/cron/crontab.envNcomment b/test/data/providers/cron/crontab.envNcomment deleted file mode 100644 index 44d41f535..000000000 --- a/test/data/providers/cron/crontab.envNcomment +++ /dev/null @@ -1,12 +0,0 @@ ---- -- | - # comment 9 - env10=val - * * * * * command11 - -- - :record_type: :comment - :line: "# comment 9" - - :record_type: :environment - :line: env10=val - - :command: command11 - :record_type: :crontab diff --git a/test/data/providers/cron/crontab.envNname b/test/data/providers/cron/crontab.envNname deleted file mode 100644 index 7cbc3fce1..000000000 --- a/test/data/providers/cron/crontab.envNname +++ /dev/null @@ -1,11 +0,0 @@ ---- -- | - env6=val - # Puppet Name: name7 - * * * * * command8 - -- - :record_type: :environment - :line: env6=val - - :command: command8 - :record_type: :crontab - :name: name7 diff --git a/test/data/providers/cron/crontab.multirecords b/test/data/providers/cron/crontab.multirecords deleted file mode 100644 index 44d41f535..000000000 --- a/test/data/providers/cron/crontab.multirecords +++ /dev/null @@ -1,12 +0,0 @@ ---- -- | - # comment 9 - env10=val - * * * * * command11 - -- - :record_type: :comment - :line: "# comment 9" - - :record_type: :environment - :line: env10=val - - :command: command11 - :record_type: :crontab diff --git a/test/data/providers/cron/crontab_collections.yaml b/test/data/providers/cron/crontab_collections.yaml deleted file mode 100644 index b323830d5..000000000 --- a/test/data/providers/cron/crontab_collections.yaml +++ /dev/null @@ -1,44 +0,0 @@ ---- -:with_name: -- :name -- :spaces_in_command_with_times -:with_env: -- :environment -- :spaces_in_command_with_times -:simple: -- :spaces_in_command_with_times -:with_multiple_envs: -- :environment -- :lowercase_environment -- :spaces_in_command_with_times -:with_name_and_env: -- :name_with_spaces -- :another_env -- :spaces_in_command_with_times -:with_name_and_multiple_envs: -- :long_name -- :another_env -- :fourth_env -- :spaces_in_command_with_times ---- -:with_name: -- :name -- :spaces_in_command_with_times -:with_env: -- :environment -- :spaces_in_command_with_times -:simple: -- :spaces_in_command_with_times -:with_multiple_envs: -- :environment -- :lowercase_environment -- :spaces_in_command_with_times -:with_name_and_env: -- :name_with_spaces -- :another_env -- :spaces_in_command_with_times -:with_name_and_multiple_envs: -- :long_name -- :another_env -- :fourth_env -- :spaces_in_command_with_times diff --git a/test/data/providers/cron/crontab_multiple_with_env.yaml b/test/data/providers/cron/crontab_multiple_with_env.yaml deleted file mode 100644 index ff7af8eb3..000000000 --- a/test/data/providers/cron/crontab_multiple_with_env.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- | - # comment 1 - # Puppet Name: name2 - env3=val - * * * * * command4 - # Puppet Name: name with spaces - env3=val - env4=other - * * * * * command5 - # comment 5 - -- - :record_type: :comment - :line: "# comment 1" - - :command: command4 - :environment: - - env3=val - :name: name2 - :record_type: :crontab - - :command: command5 - :environment: - - env3=val - - env4=other - :name: name with spaces - :record_type: :crontab - - :record_type: :comment - :line: "# comment 5" ---- -- | - # comment 1 - # Puppet Name: name2 - env3=val - * * * * * command4 - # Puppet Name: name with spaces - env3=val - env4=other - * * * * * command5 - # comment 5 - -- - :record_type: :comment - :line: "# comment 1" - - :command: command4 - :environment: - - env3=val - :name: name2 - :record_type: :crontab - - :command: command5 - :environment: - - env3=val - - env4=other - :name: name with spaces - :record_type: :crontab - - :record_type: :comment - :line: "# comment 5" diff --git a/test/data/providers/cron/examples/freebsd b/test/data/providers/cron/examples/freebsd deleted file mode 100644 index fba1e310b..000000000 --- a/test/data/providers/cron/examples/freebsd +++ /dev/null @@ -1,2 +0,0 @@ -@daily /path/to/some/job -@reboot /path/to/some/job diff --git a/test/data/providers/cron/examples/one b/test/data/providers/cron/examples/one deleted file mode 100644 index 9cddf97e7..000000000 --- a/test/data/providers/cron/examples/one +++ /dev/null @@ -1,14 +0,0 @@ -TZ=Europe/Paris -# -# Some comments -# and more comments -# -SHELL=/bin/sh -0 0 * * * /usr/local/bin/savelogs --period --postmovehook="/usr/local/apache/bin/apachectl graceful" --apacheconf=/www/conf/httpd.conf -58 23 * * * /usr/bin/diff /var/log/slow-queries.log /backup/var/log/slow-queries.log -59 23 * * * /usr/bin/diff /var/db/mysql/*.err /backup/var/db/mysql/*.err -0 7 * * Mon cd /usr/local/install; find . -maxdepth 1 -type f -mtime -30 -exec ls -l {} \; | mail -E -s 'Recent vinstall kits' vinstall@domain.com -#* * * * * /bin/ls|mail -s 'test !!' gg@domain.com -47 4 * * 1 /usr/local/bin/wget 'ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY' -O /home/installman/www/install.domain.com/inst/MIRRORED.BY -25 */2 * * * /usr/local/bin/freshclam --quiet -#* * * * * /root/top.sh diff --git a/test/data/providers/cron/examples/openbsd b/test/data/providers/cron/examples/openbsd deleted file mode 100644 index d77597da0..000000000 --- a/test/data/providers/cron/examples/openbsd +++ /dev/null @@ -1,20 +0,0 @@ -# -SHELL=/bin/sh -PATH=/bin:/sbin:/usr/bin:/usr/sbin -HOME=/var/log -# -#minute hour mday month wday command -# -# sendmail clientmqueue runner -*/30 * * * * /usr/sbin/sendmail -L sm-msp-queue -Ac -q -# -# rotate log files every hour, if necessary -0 * * * * /usr/bin/newsyslog -# send log file notifications, if necessary -#1-59 * * * * /usr/bin/newsyslog -m -# -# do daily/weekly/monthly maintenance -30 1 * * * /bin/sh /etc/daily 2>&1 | tee /var/log/daily.out | mail -s "`/bin/hostname` daily output" root -30 3 * * 6 /bin/sh /etc/weekly 2>&1 | tee /var/log/weekly.out | mail -s "`/bin/hostname` weekly output" root -30 5 1 * * /bin/sh /etc/monthly 2>&1 | tee /var/log/monthly.out | mail -s "`/bin/hostname` monthly output" root -#0 * * * * /usr/libexec/spamd-setup diff --git a/test/data/providers/host/parsed/valid_hosts b/test/data/providers/host/parsed/valid_hosts deleted file mode 100644 index 24636295d..000000000 --- a/test/data/providers/host/parsed/valid_hosts +++ /dev/null @@ -1,19 +0,0 @@ -# Some leading comment, that should be ignored -# The next line is empty so it should be ignored - -::1 localhost - -# We now try another delimiter: Several tabs -127.0.0.1 localhost - -# No test trailing spaces -10.0.0.1 host1 - -# Ok its time to test aliases -2001:252:0:1::2008:8 ipv6host alias1 -192.168.0.1 ipv4host alias2 alias3 - -# Testing inlinecomments now -192.168.0.2 host3 # This is host3 -192.168.0.3 host4 alias10 # This is host4 -192.168.0.4 host5 alias11 alias12 # This is host5 diff --git a/test/data/providers/mailalias/aliases/test1 b/test/data/providers/mailalias/aliases/test1 deleted file mode 100644 index ecf532213..000000000 --- a/test/data/providers/mailalias/aliases/test1 +++ /dev/null @@ -1,28 +0,0 @@ -# Basic system aliases -- these MUST be present -MAILER-DAEMON: postmaster -postmaster: root - -# General redirections for pseudo accounts -bin: root -daemon: root -named: root -nobody: root -uucp: root -www: root -ftp-bugs: root -postfix: root - -# Put your local aliases here. - -# Well-known aliases -manager: root -dumper: root -operator: root -abuse: postmaster - -# trap decode to catch security attacks -decode: root - -# Other tests -anothertest: "|/path/to/rt-mailgate --queue 'another test' --action correspond --url http://my.com/" -test: "|/path/to/rt-mailgate --queue 'test' --action correspond --url http://my.com/" diff --git a/test/data/providers/mount/parsed/aix.mount b/test/data/providers/mount/parsed/aix.mount deleted file mode 100644 index 380dbc5ae..000000000 --- a/test/data/providers/mount/parsed/aix.mount +++ /dev/null @@ -1,7 +0,0 @@ -node mounted mounted over vfs date options ----- ------- ------------ --- ------------ ------------------- - /dev/hd0 / jfs Dec 17 08:04 rw, log =/dev/hd8 - /dev/hd3 /tmp jfs Dec 17 08:04 rw, log =/dev/hd8 - /dev/hd1 /home jfs Dec 17 08:06 rw, log =/dev/hd8 - /dev/hd2 /usr jfs Dec 17 08:06 rw, log =/dev/hd8 -sue /home/local/src /usr/code nfs Dec 17 08:06 ro, log =/dev/hd8 diff --git a/test/data/providers/mount/parsed/darwin.mount b/test/data/providers/mount/parsed/darwin.mount deleted file mode 100644 index 1bdfcf89a..000000000 --- a/test/data/providers/mount/parsed/darwin.mount +++ /dev/null @@ -1,6 +0,0 @@ -/dev/disk0s2 on / (hfs, local, journaled) -devfs on /dev (devfs, local, nobrowse) -map -hosts on /net (autofs, nosuid, automounted, nobrowse) -map auto_home on /home (autofs, automounted, nobrowse) -/dev/disk0s3 on /usr (hfs, local, journaled) -/dev/fake on /ghost (hfs, local, journaled) diff --git a/test/data/providers/mount/parsed/hpux.mount b/test/data/providers/mount/parsed/hpux.mount deleted file mode 100644 index d414fa47a..000000000 --- a/test/data/providers/mount/parsed/hpux.mount +++ /dev/null @@ -1,17 +0,0 @@ -/ on rpool/ROOT/opensolaris read/write/setuid/devices/dev=2d90002 on Wed Dec 31 16:00:00 1969 -/devices on /devices read/write/setuid/devices/dev=4a00000 on Thu Feb 17 14:34:02 2011 -/dev on /dev read/write/setuid/devices/dev=4a40000 on Thu Feb 17 14:34:02 2011 -/system/contract on ctfs read/write/setuid/devices/dev=4ac0001 on Thu Feb 17 14:34:02 2011 -/proc on proc read/write/setuid/devices/dev=4b00000 on Thu Feb 17 14:34:02 2011 -/etc/mnttab on mnttab read/write/setuid/devices/dev=4b40001 on Thu Feb 17 14:34:02 2011 -/etc/svc/volatile on swap read/write/setuid/devices/xattr/dev=4b80001 on Thu Feb 17 14:34:02 2011 -/system/object on objfs read/write/setuid/devices/dev=4bc0001 on Thu Feb 17 14:34:02 2011 -/etc/dfs/sharetab on sharefs read/write/setuid/devices/dev=4c00001 on Thu Feb 17 14:34:02 2011 -/lib/libc.so.1 on /usr/lib/libc/libc_hwcap1.so.1 read/write/setuid/devices/dev=2d90002 on Thu Feb 17 14:34:14 2011 -/dev/fd on fd read/write/setuid/devices/dev=4d00001 on Thu Feb 17 14:34:18 2011 -/tmp on swap read/write/setuid/devices/xattr/dev=4b80002 on Thu Feb 17 14:34:19 2011 -/var/run on swap read/write/setuid/devices/xattr/dev=4b80003 on Thu Feb 17 14:34:19 2011 -/export on rpool/export read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90006 on Thu Feb 17 14:37:48 2011 -/export/home on rpool/export/home read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90007 on Thu Feb 17 14:37:48 2011 -/rpool on rpool read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011 -/ghost on /dev/fake read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011 diff --git a/test/data/providers/mount/parsed/linux.mount b/test/data/providers/mount/parsed/linux.mount deleted file mode 100644 index 75dd71fd4..000000000 --- a/test/data/providers/mount/parsed/linux.mount +++ /dev/null @@ -1,5 +0,0 @@ -/dev/root on / type jfs (rw,noatime) -rc-svcdir on /lib64/rc/init.d type tmpfs (rw,nosuid,nodev,noexec,relatime,size=1024k,mode=755) -sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) -/dev/sda9 on /usr/portage type jfs (rw) -/dev/fake on /ghost type jfs (rw) diff --git a/test/data/providers/mount/parsed/solaris.mount b/test/data/providers/mount/parsed/solaris.mount deleted file mode 100644 index 26fabc575..000000000 --- a/test/data/providers/mount/parsed/solaris.mount +++ /dev/null @@ -1,6 +0,0 @@ -/ on /dev/dsk/c0t0d0s0 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Mon Mar 18 08:48:45 2002 -/proc on /proc read/write/setuid/dev=4300000 on Mon Mar 18 08:48:44 2002 -/etc/mnttab on mnttab read/write/setuid/dev=43c0000 on Mon Mar 18 08:48:44 2002 -/tmp on swap read/write/setuid/xattr/dev=2 on Mon Mar 18 08:48:52 2002 -/export/home on /dev/dsk/c0t0d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18 -/ghost on /dev/dsk/c0t1d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18 diff --git a/test/data/providers/package/testpackages.yaml b/test/data/providers/package/testpackages.yaml deleted file mode 100644 index 7d7ce0225..000000000 --- a/test/data/providers/package/testpackages.yaml +++ /dev/null @@ -1,65 +0,0 @@ ---- -- :operatingsystem: Solaris - :files: - - /usr/local/pkg/rdesktop-1.3.1-sol10-intel-local - - /usr/local/pkg/rdesktop-1.4.1-sol10-x86-local - :hardwareisa: i386 - :name: SMCrdesk - :operatingsystemrelease: "5.10" - :provider: :sun -- :operatingsystem: Solaris - :name: cabextract - :provider: :blastwave -- :operatingsystem: Solaris - :files: - - /usr/local/pkg/arc-5.21e-sol8-sparc-local - :hardwareisa: sparc - :name: SMCarc - :operatingsystemrelease: "5.8" - :provider: :sun -- :operatingsystem: Solaris - :files: - - /usr/local/pkg/arc-5.21e-sol8-intel-local - :hardwareisa: i386 - :name: SMCarc - :operatingsystemrelease: "5.8" - :provider: :sun -- :operatingsystem: OpenBSD - :files: - - ftp://ftp.usa.openbsd.org/pub/OpenBSD/3.8/packages/i386/aalib-1.2-no_x11.tgz - :name: aalib - :provider: :openbsd -- :operatingsystem: Debian - :name: zec - :provider: :apt -- :operatingsystem: Debian - :name: zec - :provider: :aptitude -- :operatingsystem: Fedora - :name: wv - :provider: :yum -- :operatingsystem: - - Fedora - - CentOS - - RedHat - :files: - - /home/luke/rpm/RPMS/noarch/enhost-1.0.1-1.noarch.rpm - - /home/luke/rpm/RPMS/noarch/enhost-1.0.2-1.noarch.rpm - :name: enhost - :provider: :rpm -- :operatingsystem: Darwin - :name: aop - :provider: :darwinports -- :operatingsystem: FreeBSD - :name: yahtzee - :provider: :ports -- :provider: :apple - :files: - - /Users/luke/Documents/Puppet/pkgtesting.pkg - :name: pkgtesting - :cleanup: rm -rf /Library/Receipts/pkgtesting.pkg/ /tmp/file -- :provider: :gem - :name: wxrubylayouts - :versions: - - 0.0.2 - - 0.0.3 diff --git a/test/data/providers/ssh_authorized_key/parsed/authorized_keys b/test/data/providers/ssh_authorized_key/parsed/authorized_keys deleted file mode 100644 index b22329dca..000000000 --- a/test/data/providers/ssh_authorized_key/parsed/authorized_keys +++ /dev/null @@ -1,7 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= francois.deppierraz@nimag.net -ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz -from="192.168.1.1",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz -from="192.168.1.1, www.reductivelabs.com",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz -ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2Vi+TdC3iOGYcIo5vGTvC9P9rjHl9RxCuZmSfn+YDFQ35RXf0waijtjp9I7GYh6R4hBjA5z0u/Pzi95LET5NfRM0Gdc0DJyvBI7K+ALBxIT383Iz6Yz4iKxe1TEJgHGM2he4+7BHkjc3kdIZqIpZjucCk4VsXSxujO4MKKvtaKK2l+kahlLQHHw/vZkDpIgL52iGVsjW9l8RLJaKHZ4mDHJN/Q/Rzn2W4EvcdHUzwhvGMwZlm8clDwITBrSsawYtnivJrQSYcmTRqJuS8wprNDrLIhTGjrwFg5WpruUuMt6fLuCqwe6TeEL+nh3DQ4g554c5aRp3oU6LGBKTvNZGWQ== francois@korn -ssh-dss AAAAB3NzaC1kc3MAAACBAMPpCYnjywOemd8LqbbmC+bePNR3/H1rXsiFwjSLhYE3bbOpvclvOzN1DruFc34m0FopVnMkP+aubjdIYF8pijl+5hg9ggB7Kno2dl0Dd1rGN/swvmhA8OpLAQv7Qt7UnXKVho3as08zYZsrHxYFu0wlnkdbsv4cy4aXyQKd4MPVAAAAFQDSyQFWg8Qt3wU05buhZ10psoR7tQAAAIEAmAhguXwUnI3P2FF5NAW/mpJUmUERdL4pyZARUyAgpf7ezwrh9TJqrvGTQNBF97Xqaivyncm5JWQdMIsTBxEFaXZGkmBta02KnWcn447qvIh7iv8XpNL6M9flCkBEZOJ4t9El0ytTSHHaiCz8A20Et+E8evWyi1kXkFDt8ML2dGgAAACBAK0X4ympbdEjgV/ZyOc+BU22u7vOnfSOUJmyar4Ax1MIDNnoyNWKnGvxRutydQcQOKQHZEU0fE8MhPFn6nLF6CoVfEl/oz0EYz3hjV4WPFpHrF5DY/rhvNj8iuneKJ5P0dy/rG6m5qey25PnHyGFVoIRlkHJvBCJT40dHs40YEjI francois@korn -ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ== diff --git a/test/data/providers/ssh_authorized_key/parsed/authorized_keys1 b/test/data/providers/ssh_authorized_key/parsed/authorized_keys1 deleted file mode 100644 index 7aa0647ca..000000000 --- a/test/data/providers/ssh_authorized_key/parsed/authorized_keys1 +++ /dev/null @@ -1,3 +0,0 @@ -1024 35 167576894966720957580065952882142495543043407324667405194097438434880798807651864847570827148390962746149410384891026772700627764845955493549511618975091512997118590589399665757714186775228807376424903966072778732134483862302766419277581465932186641863495699668069439475320990051723279127881281145164415361627 francois@korn -2048 35 27332429396020032283276339339051507284036000350350092862949624519871013308460312287866673933080560923221560798334008554200019645416448528663000202951887890525621015333936122655294782671001073795264378070156670395703161543893088138531854776737799752600933431638059304355933305878665812555436198516842364330938321746086651639330436648850787370397302524667456837036413634152938122227368132322078811602953517461933179827432019932348409533535942749570969101453655028606209719023224268890314608444789012688070463327764203306501923404494017305972543000091038543051645924928018568725584728655193415567703220002707737714942757 francois@korn -from="192.168.1.1",command="/bin/false",no-pty,no-port-forwarding 2048 35 27332429396020032283276339339051507284036000350350092862949624519871013308460312287866673933080560923221560798334008554200019645416448528663000202951887890525621015333936122655294782671001073795264378070156670395703161543893088138531854776737799752600933431638059304355933305878665812555436198516842364330938321746086651639330436648850787370397302524667456837036413634152938122227368132322078811602953517461933179827432019932348409533535942749570969101453655028606209719023224268890314608444789012688070463327764203306501923404494017305972543000091038543051645924928018568725584728655193415567703220002707737714942757 francois@korn diff --git a/test/data/providers/ssh_authorized_key/parsed/authorized_keys2 b/test/data/providers/ssh_authorized_key/parsed/authorized_keys2 deleted file mode 100644 index 9bf830112..000000000 --- a/test/data/providers/ssh_authorized_key/parsed/authorized_keys2 +++ /dev/null @@ -1 +0,0 @@ -false ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz diff --git a/test/data/reports/1.yaml b/test/data/reports/1.yaml deleted file mode 100644 index bc72b8241..000000000 --- a/test/data/reports/1.yaml +++ /dev/null @@ -1,108 +0,0 @@ ---- !ruby/object:Puppet::Transaction::Report -host: culain.madstop.com -logs: -- !ruby/object:Puppet::Log - level: :notice - message: executed successfully - objectsource: true - source: //culain.madstop.com/puppetserver/exec=/bin/echo testing/returns - tags: - - :puppetserver - - :puppetserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :exec - - :returns - time: 2006-09-21 13:06:59.867782 -05:00 -- !ruby/object:Puppet::Log - level: :notice - message: ensure changed 'stopped' to 'running' - objectsource: true - source: //culain.madstop.com/mailserver/service=spamassassin/ensure - tags: - - :mailserver - - :mailserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :service - - :ensure - time: 2006-09-21 13:07:01.336511 -05:00 -- !ruby/object:Puppet::Log - level: :notice - message: ensure changed 'stopped' to 'running' - objectsource: true - source: //culain.madstop.com/mailserver/service=courier-imap-ssl/ensure - tags: - - :mailserver - - :mailserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :service - - :ensure - time: 2006-09-21 13:07:01.573506 -05:00 -- !ruby/object:Puppet::Log - level: :notice - message: ensure changed 'stopped' to 'running' - objectsource: true - source: //culain.madstop.com/mailserver/service=courier-authdaemon/ensure - tags: - - :mailserver - - :mailserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :service - - :ensure - time: 2006-09-21 13:07:01.680440 -05:00 -metrics: - time: !ruby/object:Puppet::Metric - label: Time - name: time - values: - - - :config_retrieval - - Config retrieval - - 2.26467204093933 - - - :total - - Total - - 21.7894113063812 - changes: !ruby/object:Puppet::Metric - label: Changes - name: changes - values: - - - :total - - Total - - 4 - objects: !ruby/object:Puppet::Metric - label: Objects - name: objects - values: - - - :scheduled - - Scheduled - - 78 - - - :applied - - Applied - - 4 - - - :restarted - - Restarted - - 0 - - - :skipped - - Skipped - - 0 - - - :failed_restarts - - Failed restarts - - 0 - - - :out_of_sync - - Out of sync - - 4 - - - :failed - - Failed - - 0 - - - :total - - Total - - 79 -records: {} - -time: 2006-09-21 13:07:06.825337 -05:00 diff --git a/test/data/reports/2.yaml b/test/data/reports/2.yaml deleted file mode 100644 index 3805e90f5..000000000 --- a/test/data/reports/2.yaml +++ /dev/null @@ -1,108 +0,0 @@ ---- !ruby/object:Puppet::Transaction::Report -host: culain.madstop.com -logs: -- !ruby/object:Puppet::Log - level: :notice - message: executed successfully - objectsource: true - source: //culain.madstop.com/puppetserver/exec=/bin/echo testing/returns - tags: - - :puppetserver - - :puppetserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :exec - - :returns - time: 2006-09-21 13:06:59.867782 -05:00 -- !ruby/object:Puppet::Log - level: :notice - message: ensure changed 'stopped' to 'running' - objectsource: true - source: //culain.madstop.com/mailserver/service=spamassassin/ensure - tags: - - :mailserver - - :mailserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :service - - :ensure - time: 2006-09-21 13:07:01.336511 -05:00 -- !ruby/object:Puppet::Log - level: :notice - message: ensure changed 'stopped' to 'running' - objectsource: true - source: //culain.madstop.com/mailserver/service=courier-imap-ssl/ensure - tags: - - :mailserver - - :mailserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :service - - :ensure - time: 2006-09-21 13:07:01.573506 -05:00 -- !ruby/object:Puppet::Log - level: :notice - message: ensure changed 'stopped' to 'running' - objectsource: true - source: //culain.madstop.com/mailserver/service=courier-authdaemon/ensure - tags: - - :mailserver - - :mailserver - - :basenode - - :"culain.madstop.com" - - :puppet - - :service - - :ensure - time: 2006-09-21 13:07:01.680440 -05:00 -metrics: - time: !ruby/object:Puppet::Metric - label: Time - name: time - values: - - - :config_retrieval - - Config retrieval - - 2.26467204093933 - - - :total - - Total - - 21.7894113063812 - changes: !ruby/object:Puppet::Metric - label: Changes - name: changes - values: - - - :total - - Total - - 4 - objects: !ruby/object:Puppet::Metric - label: Objects - name: objects - values: - - - :scheduled - - Scheduled - - 78 - - - :applied - - Applied - - 4 - - - :restarted - - Restarted - - 0 - - - :skipped - - Skipped - - 0 - - - :failed_restarts - - Failed restarts - - 0 - - - :out_of_sync - - Out of sync - - 4 - - - :failed - - Failed - - 0 - - - :total - - Total - - 79 -records: {} - -time: 2006-09-21 13:07:06.825337 -05:00 diff --git a/test/data/reports/tagmail_failers.conf b/test/data/reports/tagmail_failers.conf deleted file mode 100644 index d116b5fc7..000000000 --- a/test/data/reports/tagmail_failers.conf +++ /dev/null @@ -1,3 +0,0 @@ -tag: -: abuse@domain.com -invalid!tag: abuse@domain.com diff --git a/test/data/reports/tagmail_passers.conf b/test/data/reports/tagmail_passers.conf deleted file mode 100644 index ae6d2e7f2..000000000 --- a/test/data/reports/tagmail_passers.conf +++ /dev/null @@ -1,30 +0,0 @@ -# A comment -# or maybe two -# plus some blank lines - # with some blanks plus a comment - -# a simple tag report -one: abuse@domain.com - -# with weird spacing - one : abuse@domain.com - -# with multiple tags -one, two: abuse@domain.com - -# again with the weird syntax - one , two : abuse@domain.com - -# Some negations -one, !two: abuse@domain.com - -# some oddly-formatted tags -one, two-three, !four-five, !six: abuse@domain.com - -# multiple addresses -one, two: abuse@domain.com, testing@domain.com - -# and with weird spacing -one, two: abuse@domain.com , testing@domain.com - -# and a trailing comment diff --git a/test/data/snippets/aliastest.pp b/test/data/snippets/aliastest.pp deleted file mode 100644 index f2b61592e..000000000 --- a/test/data/snippets/aliastest.pp +++ /dev/null @@ -1,16 +0,0 @@ -file { "a file": - path => "/tmp/aliastest", - ensure => file -} - -file { "another": - path => "/tmp/aliastest2", - ensure => file, - require => File["a file"] -} - -file { "a third": - path => "/tmp/aliastest3", - ensure => file, - require => File["/tmp/aliastest"] -} diff --git a/test/data/snippets/append.pp b/test/data/snippets/append.pp deleted file mode 100644 index 20cbda662..000000000 --- a/test/data/snippets/append.pp +++ /dev/null @@ -1,11 +0,0 @@ -$var=['/tmp/file1','/tmp/file2'] - -class arraytest { - $var += ['/tmp/file3', '/tmp/file4'] - file { - $var: - content => "test" - } -} - -include arraytest diff --git a/test/data/snippets/argumentdefaults b/test/data/snippets/argumentdefaults deleted file mode 100644 index eac9dd757..000000000 --- a/test/data/snippets/argumentdefaults +++ /dev/null @@ -1,14 +0,0 @@ -# $Id$ - -define testargs($file, $mode = 755) { - file { $file: ensure => file, mode => $mode } -} - -testargs { "testingname": - file => "/tmp/argumenttest1" -} - -testargs { "testingother": - file => "/tmp/argumenttest2", - mode => 644 -} diff --git a/test/data/snippets/arithmetic_expression.pp b/test/data/snippets/arithmetic_expression.pp deleted file mode 100644 index aae98a4db..000000000 --- a/test/data/snippets/arithmetic_expression.pp +++ /dev/null @@ -1,8 +0,0 @@ - -$one = 1.30 -$two = 2.034e-2 - -$result = ((( $two + 2) / $one) + 4 * 5.45) - (6 << 7) + (0x800 + -9) - - -notice("result is $result == 1295.87692307692") \ No newline at end of file diff --git a/test/data/snippets/arraytrailingcomma.pp b/test/data/snippets/arraytrailingcomma.pp deleted file mode 100644 index a410f9553..000000000 --- a/test/data/snippets/arraytrailingcomma.pp +++ /dev/null @@ -1,3 +0,0 @@ -file { - ["/tmp/arraytrailingcomma1","/tmp/arraytrailingcomma2", ]: content => "tmp" -} diff --git a/test/data/snippets/casestatement.pp b/test/data/snippets/casestatement.pp deleted file mode 100644 index 66ecd72b9..000000000 --- a/test/data/snippets/casestatement.pp +++ /dev/null @@ -1,65 +0,0 @@ -# $Id$ - -$var = "value" - -case $var { - "nope": { - file { "/tmp/fakefile": mode => 644, ensure => file } - } - "value": { - file { "/tmp/existsfile": mode => 755, ensure => file } - } -} - -$ovar = "yayness" - -case $ovar { - "fooness": { - file { "/tmp/nostillexistsfile": mode => 644, ensure => file } - } - "booness", "yayness": { - case $var { - "nep": { - file { "/tmp/noexistsfile": mode => 644, ensure => file } - } - "value": { - file { "/tmp/existsfile2": mode => 755, ensure => file } - } - } - } -} - -case $ovar { - "fooness": { - file { "/tmp/nostillexistsfile": mode => 644, ensure => file } - } - default: { - file { "/tmp/existsfile3": mode => 755, ensure => file } - } -} - -$bool = true - -case $bool { - true: { - file { "/tmp/existsfile4": mode => 755, ensure => file } - } -} - -$yay = yay -$a = yay -$b = boo - -case $yay { - $a: { file { "/tmp/existsfile5": mode => 755, ensure => file } } - $b: { file { "/tmp/existsfile5": mode => 644, ensure => file } } - default: { file { "/tmp/existsfile5": mode => 711, ensure => file } } - -} - -$regexvar = "exists regex" -case $regexvar { - "no match": { file { "/tmp/existsfile6": mode => 644, ensure => file } } - /(.*) regex$/: { file { "/tmp/${1}file6": mode => 755, ensure => file } } - default: { file { "/tmp/existsfile6": mode => 711, ensure => file } } -} diff --git a/test/data/snippets/classheirarchy.pp b/test/data/snippets/classheirarchy.pp deleted file mode 100644 index 36619d8b9..000000000 --- a/test/data/snippets/classheirarchy.pp +++ /dev/null @@ -1,15 +0,0 @@ -# $Id$ - -class base { - file { "/tmp/classheir1": ensure => file, mode => 755 } -} - -class sub1 inherits base { - file { "/tmp/classheir2": ensure => file, mode => 755 } -} - -class sub2 inherits base { - file { "/tmp/classheir3": ensure => file, mode => 755 } -} - -include sub1, sub2 diff --git a/test/data/snippets/classincludes.pp b/test/data/snippets/classincludes.pp deleted file mode 100644 index bd5b44ed7..000000000 --- a/test/data/snippets/classincludes.pp +++ /dev/null @@ -1,17 +0,0 @@ -# $Id$ - -class base { - file { "/tmp/classincludes1": ensure => file, mode => 755 } -} - -class sub1 inherits base { - file { "/tmp/classincludes2": ensure => file, mode => 755 } -} - -class sub2 inherits base { - file { "/tmp/classincludes3": ensure => file, mode => 755 } -} - -$sub = "sub2" - -include sub1, $sub diff --git a/test/data/snippets/classpathtest b/test/data/snippets/classpathtest deleted file mode 100644 index 580333369..000000000 --- a/test/data/snippets/classpathtest +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ - -define mytype { - file { "/tmp/classtest": ensure => file, mode => 755 } -} - -class testing { - mytype { "componentname": } -} - -include testing diff --git a/test/data/snippets/collection.pp b/test/data/snippets/collection.pp deleted file mode 100644 index bc29510a9..000000000 --- a/test/data/snippets/collection.pp +++ /dev/null @@ -1,10 +0,0 @@ -class one { - @file { "/tmp/colltest1": content => "one" } - @file { "/tmp/colltest2": content => "two" } -} - -class two { - File <| content == "one" |> -} - -include one, two diff --git a/test/data/snippets/collection_override.pp b/test/data/snippets/collection_override.pp deleted file mode 100644 index b1b39ab16..000000000 --- a/test/data/snippets/collection_override.pp +++ /dev/null @@ -1,8 +0,0 @@ -@file { - "/tmp/collection": - content => "whatever" -} - -File<| |> { - mode => 0600 -} diff --git a/test/data/snippets/collection_within_virtual_definitions.pp b/test/data/snippets/collection_within_virtual_definitions.pp deleted file mode 100644 index 3c21468b0..000000000 --- a/test/data/snippets/collection_within_virtual_definitions.pp +++ /dev/null @@ -1,20 +0,0 @@ -define test($name) { - file {"/tmp/collection_within_virtual_definitions1_$name.txt": - content => "File name $name\n" - } - Test2 <||> -} - -define test2() { - file {"/tmp/collection_within_virtual_definitions2_$name.txt": - content => "This is a test\n" - } -} - -node default { - @test {"foo": - name => "foo" - } - @test2 {"foo2": } - Test <||> -} diff --git a/test/data/snippets/componentmetaparams.pp b/test/data/snippets/componentmetaparams.pp deleted file mode 100644 index 7d9f0c2c1..000000000 --- a/test/data/snippets/componentmetaparams.pp +++ /dev/null @@ -1,11 +0,0 @@ -file { "/tmp/component1": - ensure => file -} - -define thing { - file { $name: ensure => file } -} - -thing { "/tmp/component2": - require => File["/tmp/component1"] -} diff --git a/test/data/snippets/componentrequire.pp b/test/data/snippets/componentrequire.pp deleted file mode 100644 index a61d2050c..000000000 --- a/test/data/snippets/componentrequire.pp +++ /dev/null @@ -1,8 +0,0 @@ -define testfile($mode) { - file { $name: mode => $mode, ensure => present } -} - -testfile { "/tmp/testing_component_requires2": mode => 755 } - -file { "/tmp/testing_component_requires1": mode => 755, ensure => present, - require => Testfile["/tmp/testing_component_requires2"] } diff --git a/test/data/snippets/deepclassheirarchy.pp b/test/data/snippets/deepclassheirarchy.pp deleted file mode 100644 index 249e6334d..000000000 --- a/test/data/snippets/deepclassheirarchy.pp +++ /dev/null @@ -1,23 +0,0 @@ -# $Id$ - -class base { - file { "/tmp/deepclassheir1": ensure => file, mode => 755 } -} - -class sub1 inherits base { - file { "/tmp/deepclassheir2": ensure => file, mode => 755 } -} - -class sub2 inherits sub1 { - file { "/tmp/deepclassheir3": ensure => file, mode => 755 } -} - -class sub3 inherits sub2 { - file { "/tmp/deepclassheir4": ensure => file, mode => 755 } -} - -class sub4 inherits sub3 { - file { "/tmp/deepclassheir5": ensure => file, mode => 755 } -} - -include sub4 diff --git a/test/data/snippets/defineoverrides.pp b/test/data/snippets/defineoverrides.pp deleted file mode 100644 index c68b139e3..000000000 --- a/test/data/snippets/defineoverrides.pp +++ /dev/null @@ -1,17 +0,0 @@ -# $Id$ - -$file = "/tmp/defineoverrides1" - -define myfile($mode) { - file { $name: ensure => file, mode => $mode } -} - -class base { - myfile { $file: mode => 644 } -} - -class sub inherits base { - Myfile[$file] { mode => 755, } # test the end-comma -} - -include sub diff --git a/test/data/snippets/emptyclass.pp b/test/data/snippets/emptyclass.pp deleted file mode 100644 index 48047e748..000000000 --- a/test/data/snippets/emptyclass.pp +++ /dev/null @@ -1,9 +0,0 @@ -# $Id$ - -define component { -} - -class testing { -} - -include testing diff --git a/test/data/snippets/emptyexec.pp b/test/data/snippets/emptyexec.pp deleted file mode 100644 index 847a30d18..000000000 --- a/test/data/snippets/emptyexec.pp +++ /dev/null @@ -1,3 +0,0 @@ -exec { "touch /tmp/emptyexectest": - path => "/usr/bin:/bin" -} diff --git a/test/data/snippets/emptyifelse.pp b/test/data/snippets/emptyifelse.pp deleted file mode 100644 index 598b486ac..000000000 --- a/test/data/snippets/emptyifelse.pp +++ /dev/null @@ -1,9 +0,0 @@ - -if false { -} else { - # nothing here -} - -if true { - # still nothing -} diff --git a/test/data/snippets/falsevalues.pp b/test/data/snippets/falsevalues.pp deleted file mode 100644 index 2143b79a7..000000000 --- a/test/data/snippets/falsevalues.pp +++ /dev/null @@ -1,3 +0,0 @@ -$value = false - -file { "/tmp/falsevalues$value": ensure => file } diff --git a/test/data/snippets/filecreate b/test/data/snippets/filecreate deleted file mode 100644 index d7972c234..000000000 --- a/test/data/snippets/filecreate +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ - -file { - "/tmp/createatest": ensure => file, mode => 755; - "/tmp/createbtest": ensure => file, mode => 755 -} - -file { - "/tmp/createctest": ensure => file; - "/tmp/createdtest": ensure => file; -} diff --git a/test/data/snippets/fqdefinition.pp b/test/data/snippets/fqdefinition.pp deleted file mode 100644 index ddb0675a9..000000000 --- a/test/data/snippets/fqdefinition.pp +++ /dev/null @@ -1,5 +0,0 @@ -define one::two($ensure) { - file { "/tmp/fqdefinition": ensure => $ensure } -} - -one::two { "/tmp/fqdefinition": ensure => file } diff --git a/test/data/snippets/fqparents.pp b/test/data/snippets/fqparents.pp deleted file mode 100644 index ee2f65423..000000000 --- a/test/data/snippets/fqparents.pp +++ /dev/null @@ -1,11 +0,0 @@ -class base { - class one { - file { "/tmp/fqparent1": ensure => file } - } -} - -class two::three inherits base::one { - file { "/tmp/fqparent2": ensure => file } -} - -include two::three diff --git a/test/data/snippets/funccomma.pp b/test/data/snippets/funccomma.pp deleted file mode 100644 index 32e34f92e..000000000 --- a/test/data/snippets/funccomma.pp +++ /dev/null @@ -1,5 +0,0 @@ -@file { - ["/tmp/funccomma1","/tmp/funccomma2"]: content => "1" -} - -realize( File["/tmp/funccomma1"], File["/tmp/funccomma2"] , ) diff --git a/test/data/snippets/hash.pp b/test/data/snippets/hash.pp deleted file mode 100644 index d33249872..000000000 --- a/test/data/snippets/hash.pp +++ /dev/null @@ -1,33 +0,0 @@ - -$hash = { "file" => "/tmp/myhashfile1" } - -file { - $hash["file"]: - ensure => file, content => "content"; -} - -$hash2 = { "a" => { key => "/tmp/myhashfile2" }} - -file { - $hash2["a"][key]: - ensure => file, content => "content"; -} - -define test($a = { "b" => "c" }) { - file { - $a["b"]: - ensure => file, content => "content" - } -} - -test { - "test": - a => { "b" => "/tmp/myhashfile3" } -} - -$hash3 = { mykey => "/tmp/myhashfile4" } -$key = "mykey" - -file { - $hash3[$key]: ensure => file, content => "content" -} diff --git a/test/data/snippets/ifexpression.pp b/test/data/snippets/ifexpression.pp deleted file mode 100644 index 29a637291..000000000 --- a/test/data/snippets/ifexpression.pp +++ /dev/null @@ -1,12 +0,0 @@ -$one = 1 -$two = 2 - -if ($one < $two) and (($two < 3) or ($two == 2)) { - notice("True!") -} - -if "test regex" =~ /(.*) regex/ { - file { - "/tmp/${1}iftest": ensure => file, mode => 0755 - } -} diff --git a/test/data/snippets/implicititeration b/test/data/snippets/implicititeration deleted file mode 100644 index 6f34cb29c..000000000 --- a/test/data/snippets/implicititeration +++ /dev/null @@ -1,15 +0,0 @@ -# $Id$ - -$files = ["/tmp/iterationatest", "/tmp/iterationbtest"] - -file { $files: ensure => file, mode => 755 } - -file { ["/tmp/iterationctest", "/tmp/iterationdtest"]: - ensure => file, - mode => 755 -} - -file { - ["/tmp/iterationetest", "/tmp/iterationftest"]: ensure => file, mode => 755; - ["/tmp/iterationgtest", "/tmp/iterationhtest"]: ensure => file, mode => 755; -} diff --git a/test/data/snippets/multilinecomments.pp b/test/data/snippets/multilinecomments.pp deleted file mode 100644 index f9819c020..000000000 --- a/test/data/snippets/multilinecomments.pp +++ /dev/null @@ -1,10 +0,0 @@ - -/* -file { - "/tmp/multilinecomments": content => "pouet" -} -*/ - -/* and another one for #2333, the whitespace after the -end comment is here on purpose */ - diff --git a/test/data/snippets/multipleclass.pp b/test/data/snippets/multipleclass.pp deleted file mode 100644 index ae02edc38..000000000 --- a/test/data/snippets/multipleclass.pp +++ /dev/null @@ -1,9 +0,0 @@ -class one { - file { "/tmp/multipleclassone": content => "one" } -} - -class one { - file { "/tmp/multipleclasstwo": content => "two" } -} - -include one diff --git a/test/data/snippets/multipleinstances b/test/data/snippets/multipleinstances deleted file mode 100644 index 2f9b3c2e8..000000000 --- a/test/data/snippets/multipleinstances +++ /dev/null @@ -1,7 +0,0 @@ -# $Id$ - -file { - "/tmp/multipleinstancesa": ensure => file, mode => 755; - "/tmp/multipleinstancesb": ensure => file, mode => 755; - "/tmp/multipleinstancesc": ensure => file, mode => 755; -} diff --git a/test/data/snippets/multisubs.pp b/test/data/snippets/multisubs.pp deleted file mode 100644 index bcec69e2a..000000000 --- a/test/data/snippets/multisubs.pp +++ /dev/null @@ -1,13 +0,0 @@ -class base { - file { "/tmp/multisubtest": content => "base", mode => 644 } -} - -class sub1 inherits base { - File["/tmp/multisubtest"] { mode => 755 } -} - -class sub2 inherits base { - File["/tmp/multisubtest"] { content => sub2 } -} - -include sub1, sub2 diff --git a/test/data/snippets/namevartest b/test/data/snippets/namevartest deleted file mode 100644 index dbee1c356..000000000 --- a/test/data/snippets/namevartest +++ /dev/null @@ -1,9 +0,0 @@ -define filetest($mode, $ensure = file) { - file { $name: - mode => $mode, - ensure => $ensure - } -} - -filetest { "/tmp/testfiletest": mode => 644} -filetest { "/tmp/testdirtest": mode => 755, ensure => directory} diff --git a/test/data/snippets/scopetest b/test/data/snippets/scopetest deleted file mode 100644 index 331491766..000000000 --- a/test/data/snippets/scopetest +++ /dev/null @@ -1,13 +0,0 @@ - -$mode = 640 - -define thing { - file { "/tmp/$name": ensure => file, mode => $mode } -} - -class testing { - $mode = 755 - thing {scopetest: } -} - -include testing diff --git a/test/data/snippets/selectorvalues.pp b/test/data/snippets/selectorvalues.pp deleted file mode 100644 index d80d26c36..000000000 --- a/test/data/snippets/selectorvalues.pp +++ /dev/null @@ -1,49 +0,0 @@ -$value1 = "" -$value2 = true -$value3 = false -$value4 = yay - -$test = "yay" - -$mode1 = $value1 ? { - "" => 755, - default => 644 -} - -$mode2 = $value2 ? { - true => 755, - default => 644 -} - -$mode3 = $value3 ? { - false => 755, - default => 644 -} - -$mode4 = $value4 ? { - $test => 755, - default => 644 -} - -$mode5 = yay ? { - $test => 755, - default => 644 -} - -$mode6 = $mode5 ? { - 755 => 755 -} - -$mode7 = "test regex" ? { - /regex$/ => 755, - default => 644 -} - - -file { "/tmp/selectorvalues1": ensure => file, mode => $mode1 } -file { "/tmp/selectorvalues2": ensure => file, mode => $mode2 } -file { "/tmp/selectorvalues3": ensure => file, mode => $mode3 } -file { "/tmp/selectorvalues4": ensure => file, mode => $mode4 } -file { "/tmp/selectorvalues5": ensure => file, mode => $mode5 } -file { "/tmp/selectorvalues6": ensure => file, mode => $mode6 } -file { "/tmp/selectorvalues7": ensure => file, mode => $mode7 } diff --git a/test/data/snippets/simpledefaults b/test/data/snippets/simpledefaults deleted file mode 100644 index 63d199a68..000000000 --- a/test/data/snippets/simpledefaults +++ /dev/null @@ -1,5 +0,0 @@ -# $Id$ - -File { mode => 755 } - -file { "/tmp/defaulttest": ensure => file } diff --git a/test/data/snippets/simpleselector b/test/data/snippets/simpleselector deleted file mode 100644 index 8b9bc7292..000000000 --- a/test/data/snippets/simpleselector +++ /dev/null @@ -1,38 +0,0 @@ -# $Id$ - -$var = "value" - -file { "/tmp/snippetselectatest": - ensure => file, - mode => $var ? { - nottrue => 641, - value => 755 - } -} - -file { "/tmp/snippetselectbtest": - ensure => file, - mode => $var ? { - nottrue => 644, - default => 755 - } -} - -$othervar = "complex value" - -file { "/tmp/snippetselectctest": - ensure => file, - mode => $othervar ? { - "complex value" => 755, - default => 644 - } -} -$anothervar = Yayness - -file { "/tmp/snippetselectdtest": - ensure => file, - mode => $anothervar ? { - Yayness => 755, - default => 644 - } -} diff --git a/test/data/snippets/singleary.pp b/test/data/snippets/singleary.pp deleted file mode 100644 index 9ce56dd89..000000000 --- a/test/data/snippets/singleary.pp +++ /dev/null @@ -1,19 +0,0 @@ -# $Id$ - -file { "/tmp/singleary1": - ensure => file -} - -file { "/tmp/singleary2": - ensure => file -} - -file { "/tmp/singleary3": - ensure => file, - require => [File["/tmp/singleary1"], File["/tmp/singleary2"]] -} - -file { "/tmp/singleary4": - ensure => file, - require => [File["/tmp/singleary1"]] -} diff --git a/test/data/snippets/singlequote.pp b/test/data/snippets/singlequote.pp deleted file mode 100644 index dc876a2f8..000000000 --- a/test/data/snippets/singlequote.pp +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ - -file { "/tmp/singlequote1": - ensure => file, - content => 'a $quote' -} - -file { "/tmp/singlequote2": - ensure => file, - content => 'some "\yayness\"' -} diff --git a/test/data/snippets/singleselector.pp b/test/data/snippets/singleselector.pp deleted file mode 100644 index 520a14017..000000000 --- a/test/data/snippets/singleselector.pp +++ /dev/null @@ -1,22 +0,0 @@ -$value1 = "" -$value2 = true -$value3 = false -$value4 = yay - -$test = "yay" - -$mode1 = $value1 ? { - "" => 755 -} - -$mode2 = $value2 ? { - true => 755 -} - -$mode3 = $value3 ? { - default => 755 -} - -file { "/tmp/singleselector1": ensure => file, mode => $mode1 } -file { "/tmp/singleselector2": ensure => file, mode => $mode2 } -file { "/tmp/singleselector3": ensure => file, mode => $mode3 } diff --git a/test/data/snippets/subclass_name_duplication.pp b/test/data/snippets/subclass_name_duplication.pp deleted file mode 100755 index 10f1d75ed..000000000 --- a/test/data/snippets/subclass_name_duplication.pp +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env puppet - -class one::fake { - file { "/tmp/subclass_name_duplication1": ensure => present } -} - -class two::fake { - file { "/tmp/subclass_name_duplication2": ensure => present } -} - -include one::fake, two::fake diff --git a/test/data/snippets/tag.pp b/test/data/snippets/tag.pp deleted file mode 100644 index e6e770dd9..000000000 --- a/test/data/snippets/tag.pp +++ /dev/null @@ -1,9 +0,0 @@ -# $Id$ - -$variable = value - -tag yayness, rahness - -tag booness, $variable - -file { "/tmp/settestingness": ensure => file } diff --git a/test/data/snippets/tagged.pp b/test/data/snippets/tagged.pp deleted file mode 100644 index 7bf90a645..000000000 --- a/test/data/snippets/tagged.pp +++ /dev/null @@ -1,35 +0,0 @@ -# $Id$ - -tag testing -tag(funtest) - -class tagdefine { - $path = tagged(tagdefine) ? { - true => "true", false => "false" - } - - file { "/tmp/taggeddefine$path": ensure => file } -} - -include tagdefine - -$yayness = tagged(yayness) ? { - true => "true", false => "false" -} - -$funtest = tagged(testing) ? { - true => "true", false => "false" -} - -$both = tagged(testing, yayness) ? { - true => "true", false => "false" -} - -$bothtrue = tagged(testing, testing) ? { - true => "true", false => "false" -} - -file { "/tmp/taggedyayness$yayness": ensure => file } -file { "/tmp/taggedtesting$funtest": ensure => file } -file { "/tmp/taggedboth$both": ensure => file } -file { "/tmp/taggedbothtrue$bothtrue": ensure => file } diff --git a/test/data/snippets/virtualresources.pp b/test/data/snippets/virtualresources.pp deleted file mode 100644 index a29406b84..000000000 --- a/test/data/snippets/virtualresources.pp +++ /dev/null @@ -1,14 +0,0 @@ -class one { - @file { "/tmp/virtualtest1": content => "one" } - @file { "/tmp/virtualtest2": content => "two" } - @file { "/tmp/virtualtest3": content => "three" } - @file { "/tmp/virtualtest4": content => "four" } -} - -class two { - File <| content == "one" |> - realize File["/tmp/virtualtest2"] - realize(File["/tmp/virtualtest3"], File["/tmp/virtualtest4"]) -} - -include one, two diff --git a/test/data/types/hosts/1 b/test/data/types/hosts/1 deleted file mode 100644 index 286dcb72d..000000000 --- a/test/data/types/hosts/1 +++ /dev/null @@ -1,3 +0,0 @@ -# Do not remove the following line, or various programs -# that require network functionality will fail. -127.0.0.1 hostname.domain.net hostname localhost.localdomain localhost diff --git a/test/data/types/hosts/2 b/test/data/types/hosts/2 deleted file mode 100644 index 79b311b93..000000000 --- a/test/data/types/hosts/2 +++ /dev/null @@ -1,13 +0,0 @@ -127.0.0.1 localhost -192.168.0.3 culain.madstop.com culain -192.168.0.100 yaytest - -# The following lines are desirable for IPv6 capable hosts -# (added automatically by netbase upgrade) - -::1 ip6-localhost ip6-loopback -fe00::0 ip6-localnet -ff00::0 ip6-mcastprefix -ff02::1 ip6-allnodes -ff02::2 ip6-allrouters -ff02::3 ip6-allhosts diff --git a/test/data/types/hosts/solaris b/test/data/types/hosts/solaris deleted file mode 100644 index d62906d3c..000000000 --- a/test/data/types/hosts/solaris +++ /dev/null @@ -1,5 +0,0 @@ -# -# Internet host table -# -127.0.0.1 localhost -192.168.0.50 sol10b diff --git a/test/data/types/mailalias/file1 b/test/data/types/mailalias/file1 deleted file mode 100644 index a7cbd4ebf..000000000 --- a/test/data/types/mailalias/file1 +++ /dev/null @@ -1,183 +0,0 @@ -# This is the aliases file - it says who gets mail for whom. -# It was originally generated by `eximconfig', part of the exim package -# distributed with Debian, but it may edited by the mail system administrator. -# This file originally generated by eximconfig at Tue Jul 12345 12345:12345:12345 CDT 12345 -# See exim info section for details of the things that can be configured here. - -# Local aliases -eight-phone: 12345@domain.com -eight-pager: eight-phone -eight-sms: eight-phone -cindy-phone: 12345@domain.com -cindy-pager: cindy-phone -cindy-sms: cindy-phone - -ben-phone: 12345@txt.att.net -ben: eight -ajax: eight - -teyo: teyo@brainfinger.org - -#----------------# -# Family aliases # -#----------------# - -smithes: eight,six,two,seven,isaiah,kristen,cindy,three -smith: smithes -#morris: morrisbpaddlin@hotmail.com -#six: grendelwench@hotmail.com -two: twosmith@thirddomain.com -seven: sevensmith@thirddomain.com -isaiah: ismith@thirddomain.com -kristen: kristenwells@thirddomain.com -one-phone: 12345@otherdomain.com -one-pager: one-phone -seven-phone: 12345@otherdomain.com -seven-pager: seven-phone -seven-sms: seven-phone -ike-phone: 12345@otherdomain.com -ike-page: ike-phone -ike-sms: ike-phone -six-phone: 12345@otherdomain.com -six-page: six-phone -six-sms: six-phone -three: tferguson@mmc.edu -three-phone: 12345@otherdomain.com -three-page: three-phone -three-sms: three-phone -four-phone: 12345@otherdomain.com -four-page: four-phone -four-sms: four-phone -two-phone: 12345@otherdomain.com -two-page: two-phone -two-sms: two-phone -five-phone: 12345@otherdomain.com -five-page: five-phone -five-sms: five-phone - -#----------------# -# work aliases # -#----------------# -consulting: eight -svn: eight -info: eight -blog: eight -paypal: eight -trac: puppet-dev -dev: eight -sales: eight -training: eight -support: eight -faq: eight -puppet-docs: eight,nine@domain.com,ten@domain.com,eleven@other.com -docs: puppet-docs -jobs: eight - -# System stuff -postmaster: eight -root: eight - -daemon: root -bin: root -sys: root -sync: root -games: root -man: root -lp: root -mail: root -news: root -uucp: root -proxy: root -postgres: root -www-data: root -backup: root -operator: root -list: root -irc: root -gnats: root -nobody: root - -filemaker: eight - -hostmaster: root -usenet: root -webmaster: root -www: root -ftp: root -abuse: root -noc: root -security: root - -mailer-daemon: postmaster - -tap: one@two.com,two@three.com,three@four.com,four@five.com,five@six.com - -mailman: "|/var/lib/mailman/mail/mailman post mailman" -mailman-admin: "|/var/lib/mailman/mail/mailman admin mailman" -mailman-bounces: "|/var/lib/mailman/mail/mailman bounces mailman" -mailman-confirm: "|/var/lib/mailman/mail/mailman confirm mailman" -mailman-join: "|/var/lib/mailman/mail/mailman join mailman" -mailman-leave: "|/var/lib/mailman/mail/mailman leave mailman" -mailman-owner: "|/var/lib/mailman/mail/mailman owner mailman" -mailman-request: "|/var/lib/mailman/mail/mailman request mailman" -mailman-subscribe: "|/var/lib/mailman/mail/mailman subscribe mailman" -mailman-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe mailman" - -puppet-dev: "|/var/lib/mailman/mail/mailman post puppet-dev" -puppet-dev-admin: "|/var/lib/mailman/mail/mailman admin puppet-dev" -puppet-dev-bounces: "|/var/lib/mailman/mail/mailman bounces puppet-dev" -puppet-dev-confirm: "|/var/lib/mailman/mail/mailman confirm puppet-dev" -puppet-dev-join: "|/var/lib/mailman/mail/mailman join puppet-dev" -puppet-dev-leave: "|/var/lib/mailman/mail/mailman leave puppet-dev" -puppet-dev-owner: "|/var/lib/mailman/mail/mailman owner puppet-dev" -puppet-dev-request: "|/var/lib/mailman/mail/mailman request puppet-dev" -puppet-dev-subscribe: "|/var/lib/mailman/mail/mailman subscribe puppet-dev" -puppet-dev-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe puppet-dev" - -## puppet-commit mailing list -puppet-commit: "|/var/lib/mailman/mail/mailman post puppet-commit" -puppet-commit-admin: "|/var/lib/mailman/mail/mailman admin puppet-commit" -puppet-commit-bounces: "|/var/lib/mailman/mail/mailman bounces puppet-commit" -puppet-commit-confirm: "|/var/lib/mailman/mail/mailman confirm puppet-commit" -puppet-commit-join: "|/var/lib/mailman/mail/mailman join puppet-commit" -puppet-commit-leave: "|/var/lib/mailman/mail/mailman leave puppet-commit" -puppet-commit-owner: "|/var/lib/mailman/mail/mailman owner puppet-commit" -puppet-commit-request: "|/var/lib/mailman/mail/mailman request puppet-commit" -puppet-commit-subscribe: "|/var/lib/mailman/mail/mailman subscribe puppet-commit" -puppet-commit-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe puppet-commit" - -## bnageek mailing list -bnageek: "|/var/lib/mailman/mail/mailman post bnageek" -bnageek-admin: "|/var/lib/mailman/mail/mailman admin bnageek" -bnageek-bounces: "|/var/lib/mailman/mail/mailman bounces bnageek" -bnageek-confirm: "|/var/lib/mailman/mail/mailman confirm bnageek" -bnageek-join: "|/var/lib/mailman/mail/mailman join bnageek" -bnageek-leave: "|/var/lib/mailman/mail/mailman leave bnageek" -bnageek-owner: "|/var/lib/mailman/mail/mailman owner bnageek" -bnageek-request: "|/var/lib/mailman/mail/mailman request bnageek" -bnageek-subscribe: "|/var/lib/mailman/mail/mailman subscribe bnageek" -bnageek-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe bnageek" - -## puppet-users mailing list -puppet-users: "|/var/lib/mailman/mail/mailman post puppet-users" -puppet-users-admin: "|/var/lib/mailman/mail/mailman admin puppet-users" -puppet-users-bounces: "|/var/lib/mailman/mail/mailman bounces puppet-users" -puppet-users-confirm: "|/var/lib/mailman/mail/mailman confirm puppet-users" -puppet-users-join: "|/var/lib/mailman/mail/mailman join puppet-users" -puppet-users-leave: "|/var/lib/mailman/mail/mailman leave puppet-users" -puppet-users-owner: "|/var/lib/mailman/mail/mailman owner puppet-users" -puppet-users-request: "|/var/lib/mailman/mail/mailman request puppet-users" -puppet-users-subscribe: "|/var/lib/mailman/mail/mailman subscribe puppet-users" -puppet-users-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe puppet-users" - -## puppet-bugs mailing list -puppet-bugs: "|/var/lib/mailman/mail/mailman post puppet-bugs" -puppet-bugs-admin: "|/var/lib/mailman/mail/mailman admin puppet-bugs" -puppet-bugs-bounces: "|/var/lib/mailman/mail/mailman bounces puppet-bugs" -puppet-bugs-confirm: "|/var/lib/mailman/mail/mailman confirm puppet-bugs" -puppet-bugs-join: "|/var/lib/mailman/mail/mailman join puppet-bugs" -puppet-bugs-leave: "|/var/lib/mailman/mail/mailman leave puppet-bugs" -puppet-bugs-owner: "|/var/lib/mailman/mail/mailman owner puppet-bugs" -puppet-bugs-request: "|/var/lib/mailman/mail/mailman request puppet-bugs" -puppet-bugs-subscribe: "|/var/lib/mailman/mail/mailman subscribe puppet-bugs" -puppet-bugs-unsubscribe: "|/var/lib/mailman/mail/mailman unsubscribe puppet-bugs" diff --git a/test/data/types/mount/freebsd.fstab b/test/data/types/mount/freebsd.fstab deleted file mode 100644 index a41104236..000000000 --- a/test/data/types/mount/freebsd.fstab +++ /dev/null @@ -1,7 +0,0 @@ -# Device Mountpoint FStype Options Dump Pass# -/dev/ad0s1b none swap sw 0 0 -/dev/ad0s1a / ufs rw 1 1 -/dev/ad0s1e /tmp ufs rw 2 2 -/dev/ad0s1f /usr ufs rw 2 2 -/dev/ad0s1d /var ufs rw 2 2 -/dev/acd0 /cdrom cd9660 ro,noauto 0 0 diff --git a/test/data/types/mount/linux.fstab b/test/data/types/mount/linux.fstab deleted file mode 100644 index c94ec7fa8..000000000 --- a/test/data/types/mount/linux.fstab +++ /dev/null @@ -1,12 +0,0 @@ -# A sample fstab, typical for a Fedora system -/dev/vg00/lv00 / ext3 defaults 1 1 -LABEL=/boot /boot ext3 defaults 1 2 -devpts /dev/pts devpts gid=5,mode=620 0 -tmpfs /dev/shm tmpfs defaults 0 -LABEL=/home /home ext3 defaults 1 2 -/home /homes auto bind 0 2 -proc /proc proc defaults 0 0 -/dev/vg00/lv01 /spare ext3 defaults 1 2 -sysfs /sys sysfs defaults 0 0 -LABEL=SWAP-hda6 swap swap defaults 0 0 -/dev/sda1 /usr xfs noatime 0 0 diff --git a/test/data/types/mount/solaris.fstab b/test/data/types/mount/solaris.fstab deleted file mode 100644 index 348b9d50b..000000000 --- a/test/data/types/mount/solaris.fstab +++ /dev/null @@ -1,12 +0,0 @@ -#device device mount FS fsck mount mount -#to mount to fsck point type pass at boot options -# -fd - /dev/fd fd - no - -/proc - /proc proc - no - -/dev/dsk/c0d0s0 /dev/rdsk/c0d0s0 / ufs 1 no - -/dev/dsk/c0d0p0:boot - /boot pcfs - no - -/devices - /devices devfs - no - -ctfs - /system/contract ctfs - no - -objfs - /system/object objfs - no - -#swap - /tmp tmpfs - yes - -/dev/dsk/c0d0s2 /dev/rdsk/c0d0s2 /usr ufs 1 no - diff --git a/test/data/types/port/1 b/test/data/types/port/1 deleted file mode 100644 index 47da837f0..000000000 --- a/test/data/types/port/1 +++ /dev/null @@ -1,533 +0,0 @@ -# Network services, Internet style -# -# Note that it is presently the policy of IANA to assign a single well-known -# port number for both TCP and UDP; hence, officially ports have two entries -# even if the protocol doesn't support UDP operations. -# -# Updated from http://www.iana.org/assignments/port-numbers and other -# sources like http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services . -# New ports will be added on request if they have been officially assigned -# by IANA and used in the real-world or are needed by a debian package. -# If you need a huge list of used numbers please install the nmap package. - -tcpmux 1/tcp # TCP port service multiplexer -echo 7/tcp -echo 7/udp -discard 9/tcp sink null -discard 9/udp sink null -systat 11/tcp users -daytime 13/tcp -daytime 13/udp -netstat 15/tcp -qotd 17/tcp quote -msp 18/tcp # message send protocol -msp 18/udp -chargen 19/tcp ttytst source -chargen 19/udp ttytst source -ftp-data 20/tcp -ftp 21/tcp -fsp 21/udp fspd -ssh 22/tcp # SSH Remote Login Protocol -ssh 22/udp -telnet 23/tcp -smtp 25/tcp mail -time 37/tcp timserver -time 37/udp timserver -rlp 39/udp resource # resource location -nameserver 42/tcp name # IEN 116 -whois 43/tcp nicname -tacacs 49/tcp # Login Host Protocol (TACACS) -tacacs 49/udp -re-mail-ck 50/tcp # Remote Mail Checking Protocol -re-mail-ck 50/udp -domain 53/tcp nameserver # name-domain server -domain 53/udp nameserver -mtp 57/tcp # deprecated -tacacs-ds 65/tcp # TACACS-Database Service -tacacs-ds 65/udp -bootps 67/tcp # BOOTP server -bootps 67/udp -bootpc 68/tcp # BOOTP client -bootpc 68/udp -tftp 69/udp -gopher 70/tcp # Internet Gopher -gopher 70/udp -rje 77/tcp netrjs -finger 79/tcp -www 80/tcp http # WorldWideWeb HTTP -www 80/udp # HyperText Transfer Protocol -link 87/tcp ttylink -kerberos 88/tcp kerberos5 krb5 kerberos-sec # Kerberos v5 -kerberos 88/udp kerberos5 krb5 kerberos-sec # Kerberos v5 -supdup 95/tcp -hostnames 101/tcp hostname # usually from sri-nic -iso-tsap 102/tcp tsap # part of ISODE -acr-nema 104/tcp dicom # Digital Imag. & Comm. 300 -acr-nema 104/udp dicom # Digital Imag. & Comm. 300 -csnet-ns 105/tcp cso-ns # also used by CSO name server -csnet-ns 105/udp cso-ns -rtelnet 107/tcp # Remote Telnet -rtelnet 107/udp -pop2 109/tcp postoffice pop-2 # POP version 2 -pop2 109/udp pop-2 -pop3 110/tcp pop-3 # POP version 3 -pop3 110/udp pop-3 -sunrpc 111/tcp portmapper # RPC 4.0 portmapper -sunrpc 111/udp portmapper -auth 113/tcp authentication tap ident -sftp 115/tcp -uucp-path 117/tcp -nntp 119/tcp readnews untp # USENET News Transfer Protocol -ntp 123/tcp -ntp 123/udp # Network Time Protocol -pwdgen 129/tcp # PWDGEN service -pwdgen 129/udp # PWDGEN service -loc-srv 135/tcp epmap # Location Service -loc-srv 135/udp epmap -netbios-ns 137/tcp # NETBIOS Name Service -netbios-ns 137/udp -netbios-dgm 138/tcp # NETBIOS Datagram Service -netbios-dgm 138/udp -netbios-ssn 139/tcp # NETBIOS session service -netbios-ssn 139/udp -imap2 143/tcp imap # Interim Mail Access P 2 and 4 -imap2 143/udp imap -snmp 161/tcp # Simple Net Mgmt Protocol -snmp 161/udp # Simple Net Mgmt Protocol -snmp-trap 162/tcp snmptrap # Traps for SNMP -snmp-trap 162/udp snmptrap # Traps for SNMP -cmip-man 163/tcp # ISO mgmt over IP (CMOT) -cmip-man 163/udp -cmip-agent 164/tcp -cmip-agent 164/udp -mailq 174/tcp # Mailer transport queue for Zmailer -mailq 174/udp # Mailer transport queue for Zmailer -xdmcp 177/tcp # X Display Mgr. Control Proto -xdmcp 177/udp -nextstep 178/tcp NeXTStep NextStep # NeXTStep window -nextstep 178/udp NeXTStep NextStep # server -bgp 179/tcp # Border Gateway Protocol -bgp 179/udp -prospero 191/tcp # Cliff Neuman's Prospero -prospero 191/udp -irc 194/tcp # Internet Relay Chat -irc 194/udp -smux 199/tcp # SNMP Unix Multiplexer -smux 199/udp -at-rtmp 201/tcp # AppleTalk routing -at-rtmp 201/udp -at-nbp 202/tcp # AppleTalk name binding -at-nbp 202/udp -at-echo 204/tcp # AppleTalk echo -at-echo 204/udp -at-zis 206/tcp # AppleTalk zone information -at-zis 206/udp -qmtp 209/tcp # Quick Mail Transfer Protocol -qmtp 209/udp # Quick Mail Transfer Protocol -z3950 210/tcp wais # NISO Z39.50 database -z3950 210/udp wais -ipx 213/tcp # IPX -ipx 213/udp -imap3 220/tcp # Interactive Mail Access -imap3 220/udp # Protocol v3 -pawserv 345/tcp # Perf Analysis Workbench -pawserv 345/udp -zserv 346/tcp # Zebra server -zserv 346/udp -fatserv 347/tcp # Fatmen Server -fatserv 347/udp -rpc2portmap 369/tcp -rpc2portmap 369/udp # Coda portmapper -codaauth2 370/tcp -codaauth2 370/udp # Coda authentication server -clearcase 371/tcp Clearcase -clearcase 371/udp Clearcase -ulistserv 372/tcp # UNIX Listserv -ulistserv 372/udp -ldap 389/tcp # Lightweight Directory Access Protocol -ldap 389/udp -imsp 406/tcp # Interactive Mail Support Protocol -imsp 406/udp -https 443/tcp # http protocol over TLS/SSL -https 443/udp -snpp 444/tcp # Simple Network Paging Protocol -snpp 444/udp -microsoft-ds 445/tcp # Microsoft Naked CIFS -microsoft-ds 445/udp -saft 487/tcp # Simple Asynchronous File Transfer -saft 487/udp -isakmp 500/tcp # IPsec - Internet Security Association -isakmp 500/udp # and Key Management Protocol -rtsp 554/tcp # Real Time Stream Control Protocol -rtsp 554/udp # Real Time Stream Control Protocol -nqs 607/tcp # Network Queuing system -nqs 607/udp -npmp-local 610/tcp dqs313_qmaster # npmp-local / DQS -npmp-local 610/udp dqs313_qmaster -npmp-gui 611/tcp dqs313_execd # npmp-gui / DQS -npmp-gui 611/udp dqs313_execd -hmmp-ind 612/tcp dqs313_intercell # HMMP Indication / DQS -hmmp-ind 612/udp dqs313_intercell -ipp 631/tcp # Internet Printing Protocol -ipp 631/udp -# -# UNIX specific services -# -exec 512/tcp -biff 512/udp comsat -login 513/tcp -who 513/udp whod -shell 514/tcp cmd # no passwords used -syslog 514/udp -printer 515/tcp spooler # line printer spooler -talk 517/udp -ntalk 518/udp -route 520/udp router routed # RIP -timed 525/udp timeserver -tempo 526/tcp newdate -courier 530/tcp rpc -conference 531/tcp chat -netnews 532/tcp readnews -netwall 533/udp # for emergency broadcasts -gdomap 538/tcp # GNUstep distributed objects -gdomap 538/udp -uucp 540/tcp uucpd # uucp daemon -klogin 543/tcp # Kerberized `rlogin' (v5) -kshell 544/tcp krcmd # Kerberized `rsh' (v5) -afpovertcp 548/tcp # AFP over TCP -afpovertcp 548/udp -remotefs 556/tcp rfs_server rfs # Brunhoff remote filesystem -nntps 563/tcp snntp # NNTP over SSL -nntps 563/udp snntp -submission 587/tcp # Submission [RFC2476] -submission 587/udp -ldaps 636/tcp # LDAP over SSL -ldaps 636/udp -tinc 655/tcp # tinc control port -tinc 655/udp -silc 706/tcp -silc 706/udp -kerberos-adm 749/tcp # Kerberos `kadmin' (v5) -# -webster 765/tcp # Network dictionary -webster 765/udp -rsync 873/tcp -rsync 873/udp -ftps-data 989/tcp # FTP over SSL (data) -ftps 990/tcp -telnets 992/tcp # Telnet over SSL -telnets 992/udp -imaps 993/tcp # IMAP over SSL -imaps 993/udp -ircs 994/tcp # IRC over SSL -ircs 994/udp -pop3s 995/tcp # POP-3 over SSL -pop3s 995/udp -# -# From ``Assigned Numbers'': -# -#> The Registered Ports are not controlled by the IANA and on most systems -#> can be used by ordinary user processes or programs executed by ordinary -#> users. -# -#> Ports are used in the TCP [45,106] to name the ends of logical -#> connections which carry long term conversations. For the purpose of -#> providing services to unknown callers, a service contact port is -#> defined. This list specifies the port used by the server process as its -#> contact port. While the IANA can not control uses of these ports it -#> does register or list uses of these ports as a convienence to the -#> community. -# -socks 1080/tcp # socks proxy server -socks 1080/udp -proofd 1093/tcp -proofd 1093/udp -rootd 1094/tcp -rootd 1094/udp -openvpn 1194/tcp -openvpn 1194/udp -rmiregistry 1099/tcp # Java RMI Registry -rmiregistry 1099/udp -kazaa 1214/tcp -kazaa 1214/udp -nessus 1241/tcp # Nessus vulnerability -nessus 1241/udp # assessment scanner -lotusnote 1352/tcp lotusnotes # Lotus Note -lotusnote 1352/udp lotusnotes -ms-sql-s 1433/tcp # Microsoft SQL Server -ms-sql-s 1433/udp -ms-sql-m 1434/tcp # Microsoft SQL Monitor -ms-sql-m 1434/udp -ingreslock 1524/tcp -ingreslock 1524/udp -prospero-np 1525/tcp # Prospero non-privileged -prospero-np 1525/udp -datametrics 1645/tcp old-radius -datametrics 1645/udp old-radius -sa-msg-port 1646/tcp old-radacct -sa-msg-port 1646/udp old-radacct -kermit 1649/tcp -kermit 1649/udp -l2f 1701/tcp l2tp -l2f 1701/udp l2tp -radius 1812/tcp -radius 1812/udp -radius-acct 1813/tcp radacct # Radius Accounting -radius-acct 1813/udp radacct -unix-status 1957/tcp # remstats unix-status server -log-server 1958/tcp # remstats log server -remoteping 1959/tcp # remstats remoteping server -rtcm-sc104 2101/tcp # RTCM SC-104 IANA 1/29/99 -rtcm-sc104 2101/udp -cvspserver 2401/tcp # CVS client/server operations -cvspserver 2401/udp -venus 2430/tcp # codacon port -venus 2430/udp # Venus callback/wbc interface -venus-se 2431/tcp # tcp side effects -venus-se 2431/udp # udp sftp side effect -codasrv 2432/tcp # not used -codasrv 2432/udp # server port -codasrv-se 2433/tcp # tcp side effects -codasrv-se 2433/udp # udp sftp side effect -mon 2583/tcp # MON -mon 2583/udp -dict 2628/tcp # Dictionary server -dict 2628/udp -gpsd 2947/tcp -gpsd 2947/udp -gds_db 3050/tcp # InterBase server -gds_db 3050/udp -icpv2 3130/tcp icp # Internet Cache Protocol -icpv2 3130/udp icp -mysql 3306/tcp -mysql 3306/udp -nut 3493/tcp # Network UPS Tools -nut 3493/udp -distcc 3632/tcp # distributed compiler -distcc 3632/udp -daap 3689/tcp # Digital Audio Access Protocol -daap 3689/udp -svn 3690/tcp subversion # Subversion protocol -svn 3690/udp subversion -iax 4569/tcp # Inter-Asterisk eXchange -iax 4569/udp -radmin-port 4899/tcp # RAdmin Port -radmin-port 4899/udp -rfe 5002/udp # Radio Free Ethernet -rfe 5002/tcp -sip 5060/tcp # Session Initiation Protocol -sip 5060/udp -sip-tls 5061/tcp -sip-tls 5061/udp -xmpp-client 5222/tcp jabber-client # Jabber Client Connection -xmpp-client 5222/udp jabber-client -xmpp-server 5269/tcp jabber-server # Jabber Server Connection -xmpp-server 5269/udp jabber-server -cfengine 5308/tcp -cfengine 5308/udp -postgresql 5432/tcp postgres # PostgreSQL Database -postgresql 5432/udp postgres -x11 6000/tcp x11-0 # X Window System -x11 6000/udp x11-0 -x11-1 6001/tcp -x11-1 6001/udp -x11-2 6002/tcp -x11-2 6002/udp -x11-3 6003/tcp -x11-3 6003/udp -x11-4 6004/tcp -x11-4 6004/udp -x11-5 6005/tcp -x11-5 6005/udp -x11-6 6006/tcp -x11-6 6006/udp -x11-7 6007/tcp -x11-7 6007/udp -gnutella-svc 6346/tcp # gnutella -gnutella-svc 6346/udp -gnutella-rtr 6347/tcp # gnutella -gnutella-rtr 6347/udp -afs3-fileserver 7000/tcp bbs # file server itself -afs3-fileserver 7000/udp bbs -afs3-callback 7001/tcp # callbacks to cache managers -afs3-callback 7001/udp -afs3-prserver 7002/tcp # users & groups database -afs3-prserver 7002/udp -afs3-vlserver 7003/tcp # volume location database -afs3-vlserver 7003/udp -afs3-kaserver 7004/tcp # AFS/Kerberos authentication -afs3-kaserver 7004/udp -afs3-volser 7005/tcp # volume managment server -afs3-volser 7005/udp -afs3-errors 7006/tcp # error interpretation service -afs3-errors 7006/udp -afs3-bos 7007/tcp # basic overseer process -afs3-bos 7007/udp -afs3-update 7008/tcp # server-to-server updater -afs3-update 7008/udp -afs3-rmtsys 7009/tcp # remote cache manager service -afs3-rmtsys 7009/udp -font-service 7100/tcp xfs # X Font Service -font-service 7100/udp xfs -bacula-dir 9101/tcp # Bacula Director -bacula-dir 9101/udp -bacula-fd 9102/tcp # Bacula File Daemon -bacula-fd 9102/udp -bacula-sd 9103/tcp # Bacula Storage Daemon -bacula-sd 9103/udp -amanda 10080/tcp # amanda backup services -amanda 10080/udp -hkp 11371/tcp # OpenPGP HTTP Keyserver -hkp 11371/udp # OpenPGP HTTP Keyserver -bprd 13720/tcp # VERITAS NetBackup -bprd 13720/udp -bpdbm 13721/tcp # VERITAS NetBackup -bpdbm 13721/udp -bpjava-msvc 13722/tcp # BP Java MSVC Protocol -bpjava-msvc 13722/udp -vnetd 13724/tcp # Veritas Network Utility -vnetd 13724/udp -bpcd 13782/tcp # VERITAS NetBackup -bpcd 13782/udp -vopied 13783/tcp # VERITAS NetBackup -vopied 13783/udp -wnn6 22273/tcp # wnn6 -wnn6 22273/udp - -# -# Datagram Delivery Protocol services -# -rtmp 1/ddp # Routing Table Maintenance Protocol -nbp 2/ddp # Name Binding Protocol -echo 4/ddp # AppleTalk Echo Protocol -zip 6/ddp # Zone Information Protocol - -#========================================================================= -# The remaining port numbers are not as allocated by IANA. -#========================================================================= - -# Kerberos (Project Athena/MIT) services -# Note that these are for Kerberos v4, and are unofficial. Sites running -# v4 should uncomment these and comment out the v5 entries above. -# -kerberos4 750/udp kerberos-iv kdc # Kerberos (server) -kerberos4 750/tcp kerberos-iv kdc -kerberos_master 751/udp # Kerberos authentication -kerberos_master 751/tcp -passwd_server 752/udp # Kerberos passwd server -krb_prop 754/tcp krb5_prop hprop # Kerberos slave propagation -krbupdate 760/tcp kreg # Kerberos registration -kpasswd 761/tcp kpwd # Kerberos "passwd" -swat 901/tcp # swat -kpop 1109/tcp # Pop with Kerberos -knetd 2053/tcp # Kerberos de-multiplexor -zephyr-srv 2102/udp # Zephyr server -zephyr-clt 2103/udp # Zephyr serv-hm connection -zephyr-hm 2104/udp # Zephyr hostmanager -eklogin 2105/tcp # Kerberos encrypted rlogin -# Hmmm. Are we using Kv4 or Kv5 now? Worrying. -# The following is probably Kerberos v5 --- ajt@debian.org (11/02/2000) -kx 2111/tcp # X over Kerberos -iprop 2121/tcp # incremental propagation -# -# Unofficial but necessary (for NetBSD) services -# -supfilesrv 871/tcp # SUP server -supfiledbg 1127/tcp # SUP debugging - -# -# Services added for the Debian GNU/Linux distribution -# -linuxconf 98/tcp # LinuxConf -poppassd 106/tcp # Eudora -poppassd 106/udp -ssmtp 465/tcp smtps # SMTP over SSL -moira_db 775/tcp # Moira database -moira_update 777/tcp # Moira update protocol -moira_ureg 779/udp # Moira user registration -spamd 783/tcp # spamassassin daemon -omirr 808/tcp omirrd # online mirror -omirr 808/udp omirrd -customs 1001/tcp # pmake customs server -customs 1001/udp -skkserv 1178/tcp # skk jisho server port -predict 1210/udp # predict -- satellite tracking -rmtcfg 1236/tcp # Gracilis Packeten remote config server -wipld 1300/tcp # Wipl network monitor -xtel 1313/tcp # french minitel -xtelw 1314/tcp # french minitel -support 1529/tcp # GNATS -sieve 2000/tcp # Sieve mail filter daemon -cfinger 2003/tcp # GNU Finger -ndtp 2010/tcp # Network dictionary transfer protocol -frox 2121/tcp # frox: caching ftp proxy -ninstall 2150/tcp # ninstall service -ninstall 2150/udp -zebrasrv 2600/tcp # zebra service -zebra 2601/tcp # zebra vty -ripd 2602/tcp # ripd vty (zebra) -ripngd 2603/tcp # ripngd vty (zebra) -ospfd 2604/tcp # ospfd vty (zebra) -bgpd 2605/tcp # bgpd vty (zebra) -ospf6d 2606/tcp # ospf6d vty (zebra) -ospfapi 2607/tcp # OSPF-API -isisd 2608/tcp # ISISd vty (zebra) -afbackup 2988/tcp # Afbackup system -afbackup 2988/udp -afmbackup 2989/tcp # Afmbackup system -afmbackup 2989/udp -xtell 4224/tcp # xtell server -fax 4557/tcp # FAX transmission service (old) -hylafax 4559/tcp # HylaFAX client-server protocol (new) -distmp3 4600/tcp # distmp3host daemon -munin 4949/tcp lrrd # Munin -enbd-cstatd 5051/tcp # ENBD client statd -enbd-sstatd 5052/tcp # ENBD server statd -pcrd 5151/tcp # PCR-1000 Daemon -noclog 5354/tcp # noclogd with TCP (nocol) -noclog 5354/udp # noclogd with UDP (nocol) -hostmon 5355/tcp # hostmon uses TCP (nocol) -hostmon 5355/udp # hostmon uses UDP (nocol) -rplay 5555/udp # RPlay audio service -rplay 5555/tcp -rptp 5556/udp # Remote Play Transfer Protocol -rptp 5556/tcp -nsca 5667/tcp # Nagios Agent - NSCA -mrtd 5674/tcp # MRT Routing Daemon -bgpsim 5675/tcp # MRT Routing Simulator -canna 5680/tcp # cannaserver -sane-port 6566/tcp sane saned # SANE network scanner daemon -ircd 6667/tcp # Internet Relay Chat -zope-ftp 8021/tcp # zope management by ftp -webcache 8080/tcp # WWW caching service -tproxy 8081/tcp # Transparent Proxy -omniorb 8088/tcp # OmniORB -omniorb 8088/udp -clc-build-daemon 8990/tcp # Common lisp build daemon -xinetd 9098/tcp -mandelspawn 9359/udp mandelbrot # network mandelbrot -zope 9673/tcp # zope server -kamanda 10081/tcp # amanda backup services (Kerberos) -kamanda 10081/udp -amandaidx 10082/tcp # amanda backup services -amidxtape 10083/tcp # amanda backup services -smsqp 11201/tcp # Alamin SMS gateway -smsqp 11201/udp -xpilot 15345/tcp # XPilot Contact Port -xpilot 15345/udp -sgi-cmsd 17001/udp # Cluster membership services daemon -sgi-crsd 17002/udp -sgi-gcd 17003/udp # SGI Group membership daemon -sgi-cad 17004/tcp # Cluster Admin daemon -isdnlog 20011/tcp # isdn logging system -isdnlog 20011/udp -vboxd 20012/tcp # voice box system -vboxd 20012/udp -binkp 24554/tcp # binkp fidonet protocol -asp 27374/tcp # Address Search Protocol -asp 27374/udp -dircproxy 57000/tcp # Detachable IRC Proxy -tfido 60177/tcp # fidonet EMSI over telnet -fido 60179/tcp # fidonet EMSI over TCP - -# Local services diff --git a/test/data/types/port/darwin b/test/data/types/port/darwin deleted file mode 100644 index 3d27dd506..000000000 --- a/test/data/types/port/darwin +++ /dev/null @@ -1,11866 +0,0 @@ -# -# Network services, Internet style -# -# Note that it is presently the policy of IANA to assign a single well-known -# port number for both TCP and UDP; hence, most entries here have two entries -# even if the protocol doesn't support UDP operations. -# -# The latest IANA port assignments can be gotten from -# -# http://www.iana.org/assignments/port-numbers -# -# The Well Known Ports are those from 0 through 1023. -# The Registered Ports are those from 1024 through 49151 -# The Dynamic and/or Private Ports are those from 49152 through 65535 -# -# $FreeBSD: src/etc/services,v 1.89 2002/12/17 23:59:10 eric Exp $ -# From: @(#)services 5.8 (Berkeley) 5/9/91 -# -# WELL KNOWN PORT NUMBERS -# -rtmp 1/ddp #Routing Table Maintenance Protocol -tcpmux 1/udp # TCP Port Service Multiplexer -tcpmux 1/tcp # TCP Port Service Multiplexer -# Mark Lottor -nbp 2/ddp #Name Binding Protocol -compressnet 2/udp # Management Utility -compressnet 2/tcp # Management Utility -compressnet 3/udp # Compression Process -compressnet 3/tcp # Compression Process -# Bernie Volz -echo 4/ddp #AppleTalk Echo Protocol -# 4/tcp Unassigned -# 4/udp Unassigned -rje 5/udp # Remote Job Entry -rje 5/tcp # Remote Job Entry -# Jon Postel -zip 6/ddp #Zone Information Protocol -# 6/tcp Unassigned -# 6/udp Unassigned -echo 7/udp # Echo -echo 7/tcp # Echo -# Jon Postel -# 8/tcp Unassigned -# 8/udp Unassigned -discard 9/udp # Discard -discard 9/tcp # Discard -# Jon Postel -# 10/tcp Unassigned -# 10/udp Unassigned -systat 11/udp # Active Users -systat 11/tcp # Active Users -# Jon Postel -# 12/tcp Unassigned -# 12/udp Unassigned -daytime 13/udp # Daytime (RFC 867) -daytime 13/tcp # Daytime (RFC 867) -# Jon Postel -# 14/tcp Unassigned -# 14/udp Unassigned -# 15/tcp Unassigned [was netstat] -# 15/udp Unassigned -# 16/tcp Unassigned -# 16/udp Unassigned -qotd 17/udp # Quote of the Day -qotd 17/tcp # Quote of the Day -# Jon Postel -msp 18/udp # Message Send Protocol -msp 18/tcp # Message Send Protocol -# Rina Nethaniel <---none---> -chargen 19/udp # Character Generator -chargen 19/tcp # Character Generator -ftp-data 20/udp # File Transfer [Default Data] -ftp-data 20/tcp # File Transfer [Default Data] -ftp 21/udp # File Transfer [Control] -ftp 21/tcp # File Transfer [Control] -# Jon Postel -ssh 22/udp # SSH Remote Login Protocol -ssh 22/tcp # SSH Remote Login Protocol -# Tatu Ylonen -telnet 23/udp # Telnet -telnet 23/tcp # Telnet -# Jon Postel - 24/udp # any private mail system - 24/tcp # any private mail system -# Rick Adams -smtp 25/udp # Simple Mail Transfer -smtp 25/tcp # Simple Mail Transfer -# Jon Postel -# 26/tcp Unassigned -# 26/udp Unassigned -nsw-fe 27/udp # NSW User System FE -nsw-fe 27/tcp # NSW User System FE -# Robert Thomas -# 28/tcp Unassigned -# 28/udp Unassigned -msg-icp 29/udp # MSG ICP -msg-icp 29/tcp # MSG ICP -# Robert Thomas -# 30/tcp Unassigned -# 30/udp Unassigned -msg-auth 31/udp # MSG Authentication -msg-auth 31/tcp # MSG Authentication -# Robert Thomas -# 32/tcp Unassigned -# 32/udp Unassigned -dsp 33/udp # Display Support Protocol -dsp 33/tcp # Display Support Protocol -# Ed Cain -# 34/tcp Unassigned -# 34/udp Unassigned - 35/udp # any private printer server - 35/tcp # any private printer server -# Jon Postel -# 36/tcp Unassigned -# 36/udp Unassigned -time 37/udp # Time -time 37/tcp # Time -# Jon Postel -rap 38/udp # Route Access Protocol -rap 38/tcp # Route Access Protocol -# Robert Ullmann -rlp 39/udp # Resource Location Protocol -rlp 39/tcp # Resource Location Protocol -# Mike Accetta -# 40/tcp Unassigned -# 40/udp Unassigned -graphics 41/udp # Graphics -graphics 41/tcp # Graphics -name 42/udp nameserver # Host Name Server -name 42/tcp nameserver # Host Name Server -nicname 43/udp # Who Is -nicname 43/tcp # Who Is -mpm-flags 44/udp # MPM FLAGS Protocol -mpm-flags 44/tcp # MPM FLAGS Protocol -mpm 45/udp # Message Processing Module [recv] -mpm 45/tcp # Message Processing Module [recv] -mpm-snd 46/udp # MPM [default send] -mpm-snd 46/tcp # MPM [default send] -# Jon Postel -ni-ftp 47/udp # NI FTP -ni-ftp 47/tcp # NI FTP -# Steve Kille -auditd 48/udp # Digital Audit Daemon -auditd 48/tcp # Digital Audit Daemon -# Larry Scott -tacacs 49/udp # Login Host Protocol (TACACS) -tacacs 49/tcp # Login Host Protocol (TACACS) -# Pieter Ditmars -re-mail-ck 50/udp # Remote Mail Checking Protocol -re-mail-ck 50/tcp # Remote Mail Checking Protocol -# Steve Dorner -la-maint 51/udp # IMP Logical Address Maintenance -la-maint 51/tcp # IMP Logical Address Maintenance -# Andy Malis -xns-time 52/udp # XNS Time Protocol -xns-time 52/tcp # XNS Time Protocol -# Susie Armstrong -domain 53/udp # Domain Name Server -domain 53/tcp # Domain Name Server -# Paul Mockapetris -xns-ch 54/udp # XNS Clearinghouse -xns-ch 54/tcp # XNS Clearinghouse -# Susie Armstrong -isi-gl 55/udp # ISI Graphics Language -isi-gl 55/tcp # ISI Graphics Language -xns-auth 56/udp # XNS Authentication -xns-auth 56/tcp # XNS Authentication -# Susie Armstrong - 57/udp # any private terminal access - 57/tcp # any private terminal access -# Jon Postel -xns-mail 58/udp # XNS Mail -xns-mail 58/tcp # XNS Mail -# Susie Armstrong - 59/udp # any private file service - 59/tcp # any private file service -# Jon Postel - 60/udp # Unassigned - 60/tcp # Unassigned -ni-mail 61/udp # NI MAIL -ni-mail 61/tcp # NI MAIL -# Steve Kille -acas 62/udp # ACA Services -acas 62/tcp # ACA Services -# E. Wald -whois++ 63/udp # whois++ -whois++ 63/tcp # whois++ -# Rickard Schoultz -covia 64/udp # Communications Integrator (CI) -covia 64/tcp # Communications Integrator (CI) -# Dan Smith -tacacs-ds 65/udp # TACACS-Database Service -tacacs-ds 65/tcp # TACACS-Database Service -# Kathy Huber -sql*net 66/udp # Oracle SQL*NET -sql*net 66/tcp # Oracle SQL*NET -# Jack Haverty -bootps 67/udp # Bootstrap Protocol Server -bootps 67/tcp # Bootstrap Protocol Server -bootpc 68/udp # Bootstrap Protocol Client -bootpc 68/tcp # Bootstrap Protocol Client -# Bill Croft -tftp 69/udp # Trivial File Transfer -tftp 69/tcp # Trivial File Transfer -# David Clark -gopher 70/udp # Gopher -gopher 70/tcp # Gopher -# Mark McCahill -netrjs-1 71/udp # Remote Job Service -netrjs-1 71/tcp # Remote Job Service -netrjs-2 72/udp # Remote Job Service -netrjs-2 72/tcp # Remote Job Service -netrjs-3 73/udp # Remote Job Service -netrjs-3 73/tcp # Remote Job Service -netrjs-4 74/udp # Remote Job Service -netrjs-4 74/tcp # Remote Job Service -# Bob Braden - 75/udp # any private dial out service - 75/tcp # any private dial out service -# Jon Postel -deos 76/udp # Distributed External Object Store -deos 76/tcp # Distributed External Object Store -# Robert Ullmann - 77/udp # any private RJE service - 77/tcp # any private RJE service -# Jon Postel -vettcp 78/udp # vettcp -vettcp 78/tcp # vettcp -# Christopher Leong -finger 79/udp # Finger -finger 79/tcp # Finger -# David Zimmerman -http 80/udp www www-http # World Wide Web HTTP -http 80/tcp www www-http # World Wide Web HTTP -# Tim Berners-Lee -hosts2-ns 81/udp # HOSTS2 Name Server -hosts2-ns 81/tcp # HOSTS2 Name Server -# Earl Killian -xfer 82/udp # XFER Utility -xfer 82/tcp # XFER Utility -# Thomas M. Smith -mit-ml-dev 83/udp # MIT ML Device -mit-ml-dev 83/tcp # MIT ML Device -# David Reed <--none---> -ctf 84/udp # Common Trace Facility -ctf 84/tcp # Common Trace Facility -# Hugh Thomas -mit-ml-dev 85/udp # MIT ML Device -mit-ml-dev 85/tcp # MIT ML Device -# David Reed <--none---> -mfcobol 86/udp # Micro Focus Cobol -mfcobol 86/tcp # Micro Focus Cobol -# Simon Edwards <--none---> - 87/udp # any private terminal link - 87/tcp # any private terminal link -# Jon Postel -kerberos 88/udp # Kerberos -kerberos 88/tcp # Kerberos -# B. Clifford Neuman -su-mit-tg 89/udp # SU/MIT Telnet Gateway -su-mit-tg 89/tcp # SU/MIT Telnet Gateway -# Mark Crispin -########### PORT 90 also being used unofficially by Pointcast ######### -dnsix 90/udp # DNSIX Securit Attribute Token Map -dnsix 90/tcp # DNSIX Securit Attribute Token Map -# Charles Watt -mit-dov 91/udp # MIT Dover Spooler -mit-dov 91/tcp # MIT Dover Spooler -# Eliot Moss -npp 92/udp # Network Printing Protocol -npp 92/tcp # Network Printing Protocol -# Louis Mamakos -dcp 93/udp # Device Control Protocol -dcp 93/tcp # Device Control Protocol -# Daniel Tappan -objcall 94/udp # Tivoli Object Dispatcher -objcall 94/tcp # Tivoli Object Dispatcher -# Tom Bereiter <--none---> -supdup 95/udp # SUPDUP -supdup 95/tcp # SUPDUP -# Mark Crispin -dixie 96/udp # DIXIE Protocol Specification -dixie 96/tcp # DIXIE Protocol Specification -# Tim Howes -swift-rvf 97/udp # Swift Remote Virtural File Protocol -swift-rvf 97/tcp # Swift Remote Virtural File Protocol -# Maurice R. Turcotte -# -tacnews 98/udp # TAC News -tacnews 98/tcp # TAC News -# Jon Postel -metagram 99/udp # Metagram Relay -metagram 99/tcp # Metagram Relay -# Geoff Goodfellow -newacct 100/tcp # [unauthorized use] -hostname 101/udp # NIC Host Name Server -hostname 101/tcp # NIC Host Name Server -# Jon Postel -iso-tsap 102/udp # ISO-TSAP Class 0 -iso-tsap 102/tcp # ISO-TSAP Class 0 -# Marshall Rose -gppitnp 103/udp # Genesis Point-to-Point Trans Net -gppitnp 103/tcp # Genesis Point-to-Point Trans Net -acr-nema 104/udp # ACR-NEMA Digital Imag. & Comm. 300 -acr-nema 104/tcp # ACR-NEMA Digital Imag. & Comm. 300 -# Patrick McNamee <--none---> -cso 105/udp # CCSO name server protocol -cso 105/tcp # CCSO name server protocol -# Martin Hamilton -csnet-ns 105/udp # Mailbox Name Nameserver -csnet-ns 105/tcp # Mailbox Name Nameserver -# Marvin Solomon -3com-tsmux 106/udp # 3COM-TSMUX -3com-tsmux 106/tcp # 3COM-TSMUX -# Jeremy Siegel -########## 106 Unauthorized use by insecure poppassd protocol -rtelnet 107/udp # Remote Telnet Service -rtelnet 107/tcp # Remote Telnet Service -# Jon Postel -snagas 108/udp # SNA Gateway Access Server -snagas 108/tcp # SNA Gateway Access Server -# Kevin Murphy -pop2 109/udp # Post Office Protocol - Version 2 -pop2 109/tcp # Post Office Protocol - Version 2 -# Joyce K. Reynolds -pop3 110/udp # Post Office Protocol - Version 3 -pop3 110/tcp # Post Office Protocol - Version 3 -# Marshall Rose -sunrpc 111/udp # SUN Remote Procedure Call -sunrpc 111/tcp # SUN Remote Procedure Call -# Chuck McManis -mcidas 112/udp # McIDAS Data Transmission Protocol -mcidas 112/tcp # McIDAS Data Transmission Protocol -# Glenn Davis -auth 113/udp # Authentication Service -ident 113/tcp auth # -# Mike St. Johns -audionews 114/udp # Audio News Multicast -audionews 114/tcp # Audio News Multicast -# Martin Forssen -sftp 115/udp # Simple File Transfer Protocol -sftp 115/tcp # Simple File Transfer Protocol -# Mark Lottor -ansanotify 116/udp # ANSA REX Notify -ansanotify 116/tcp # ANSA REX Notify -# Nicola J. Howarth -uucp-path 117/udp # UUCP Path Service -uucp-path 117/tcp # UUCP Path Service -sqlserv 118/udp # SQL Services -sqlserv 118/tcp # SQL Services -# Larry Barnes -nntp 119/udp # Network News Transfer Protocol -nntp 119/tcp # Network News Transfer Protocol -# Phil Lapsley -cfdptkt 120/udp # CFDPTKT -cfdptkt 120/tcp # CFDPTKT -# John Ioannidis -erpc 121/udp # Encore Expedited Remote Pro.Call -erpc 121/tcp # Encore Expedited Remote Pro.Call -# Jack O'Neil <---none---> -smakynet 122/udp # SMAKYNET -smakynet 122/tcp # SMAKYNET -# Pierre Arnaud -ntp 123/udp # Network Time Protocol -ntp 123/tcp # Network Time Protocol -# Dave Mills -ansatrader 124/udp # ANSA REX Trader -ansatrader 124/tcp # ANSA REX Trader -# Nicola J. Howarth -locus-map 125/udp # Locus PC-Interface Net Map Ser -locus-map 125/tcp # Locus PC-Interface Net Map Ser -# Eric Peterson -nxedit 126/udp # NXEdit -nxedit 126/tcp # NXEdit -# Don Payette -###########Port 126 Previously assigned to application below####### -#unitary 126/tcp Unisys Unitary Login -#unitary 126/udp Unisys Unitary Login -# -###########Port 126 Previously assigned to application above####### -locus-con 127/udp # Locus PC-Interface Conn Server -locus-con 127/tcp # Locus PC-Interface Conn Server -# Eric Peterson -gss-xlicen 128/udp # GSS X License Verification -gss-xlicen 128/tcp # GSS X License Verification -# John Light -pwdgen 129/udp # Password Generator Protocol -pwdgen 129/tcp # Password Generator Protocol -# Frank J. Wacho -cisco-fna 130/udp # cisco FNATIVE -cisco-fna 130/tcp # cisco FNATIVE -cisco-tna 131/udp # cisco TNATIVE -cisco-tna 131/tcp # cisco TNATIVE -cisco-sys 132/udp # cisco SYSMAINT -cisco-sys 132/tcp # cisco SYSMAINT -statsrv 133/udp # Statistics Service -statsrv 133/tcp # Statistics Service -# Dave Mills -ingres-net 134/udp # INGRES-NET Service -ingres-net 134/tcp # INGRES-NET Service -# Mike Berrow <---none---> -epmap 135/udp # DCE endpoint resolution -epmap 135/tcp # DCE endpoint resolution -# Joe Pato -profile 136/udp # PROFILE Naming System -profile 136/tcp # PROFILE Naming System -# Larry Peterson -netbios-ns 137/udp # NETBIOS Name Service -netbios-ns 137/tcp # NETBIOS Name Service -netbios-dgm 138/udp # NETBIOS Datagram Service -netbios-dgm 138/tcp # NETBIOS Datagram Service -netbios-ssn 139/udp # NETBIOS Session Service -netbios-ssn 139/tcp # NETBIOS Session Service -# Jon Postel -emfis-data 140/udp # EMFIS Data Service -emfis-data 140/tcp # EMFIS Data Service -emfis-cntl 141/udp # EMFIS Control Service -emfis-cntl 141/tcp # EMFIS Control Service -# Gerd Beling -bl-idm 142/udp # Britton-Lee IDM -bl-idm 142/tcp # Britton-Lee IDM -# Susie Snitzer <---none---> -imap 143/udp # Internet Message Access Protocol -imap 143/tcp # Internet Message Access Protocol -# Mark Crispin -uma 144/udp # Universal Management Architecture -uma 144/tcp # Universal Management Architecture -# Jay Whitney -uaac 145/udp # UAAC Protocol -uaac 145/tcp # UAAC Protocol -# David A. Gomberg -iso-tp0 146/udp # ISO-IP0 -iso-tp0 146/tcp # ISO-IP0 -iso-ip 147/udp # ISO-IP -iso-ip 147/tcp # ISO-IP -# Marshall Rose -jargon 148/udp # Jargon -jargon 148/tcp # Jargon -# Bill Weinman -aed-512 149/udp # AED 512 Emulation Service -aed-512 149/tcp # AED 512 Emulation Service -# Albert G. Broscius -sql-net 150/udp # SQL-NET -sql-net 150/tcp # SQL-NET -# Martin Picard <<---none---> -hems 151/udp # HEMS -hems 151/tcp # HEMS -bftp 152/udp # Background File Transfer Program -bftp 152/tcp # Background File Transfer Program -# Annette DeSchon -sgmp 153/udp # SGMP -sgmp 153/tcp # SGMP -# Marty Schoffstahl -netsc-prod 154/udp # NETSC -netsc-prod 154/tcp # NETSC -netsc-dev 155/udp # NETSC -netsc-dev 155/tcp # NETSC -# Sergio Heker -sqlsrv 156/udp # SQL Service -sqlsrv 156/tcp # SQL Service -# Craig Rogers -knet-cmp 157/udp # KNET/VM Command/Message Protocol -knet-cmp 157/tcp # KNET/VM Command/Message Protocol -# Gary S. Malkin -pcmail-srv 158/udp # PCMail Server -pcmail-srv 158/tcp # PCMail Server -# Mark L. Lambert -nss-routing 159/udp # NSS-Routing -nss-routing 159/tcp # NSS-Routing -# Yakov Rekhter -sgmp-traps 160/udp # SGMP-TRAPS -sgmp-traps 160/tcp # SGMP-TRAPS -# Marty Schoffstahl -snmp 161/udp # SNMP -snmp 161/tcp # SNMP -snmptrap 162/udp # SNMPTRAP -snmptrap 162/tcp # SNMPTRAP -# Marshall Rose -cmip-man 163/udp # CMIP/TCP Manager -cmip-man 163/tcp # CMIP/TCP Manager -cmip-agent 164/udp # CMIP/TCP Agent -cmip-agent 164/tcp # CMIP/TCP Agent -# Amatzia Ben-Artzi <---none---> -xns-courier 165/udp # Xerox -xns-courier 165/tcp # Xerox -# Susie Armstrong -s-net 166/udp # Sirius Systems -s-net 166/tcp # Sirius Systems -# Brian Lloyd -namp 167/udp # NAMP -namp 167/tcp # NAMP -# Marty Schoffstahl -rsvd 168/udp # RSVD -rsvd 168/tcp # RSVD -# Neil Todd -send 169/udp # SEND -send 169/tcp # SEND -# William D. Wisner -print-srv 170/udp # Network PostScript -print-srv 170/tcp # Network PostScript -# Brian Reid -multiplex 171/udp # Network Innovations Multiplex -multiplex 171/tcp # Network Innovations Multiplex -cl/1 172/udp # Network Innovations CL/1 -cl/1 172/tcp # Network Innovations CL/1 -# Kevin DeVault <<---none---> -xyplex-mux 173/udp # Xyplex -xyplex-mux 173/tcp # Xyplex -# Bob Stewart -mailq 174/udp # MAILQ -mailq 174/tcp # MAILQ -# Rayan Zachariassen -vmnet 175/udp # VMNET -vmnet 175/tcp # VMNET -# Christopher Tengi -genrad-mux 176/udp # GENRAD-MUX -genrad-mux 176/tcp # GENRAD-MUX -# Ron Thornton -xdmcp 177/udp # X Display Manager Control Protocol -xdmcp 177/tcp # X Display Manager Control Protocol -# Robert W. Scheifler -nextstep 178/udp # NextStep Window Server -nextstep 178/tcp # NextStep Window Server -# Leo Hourvitz -bgp 179/udp # Border Gateway Protocol -bgp 179/tcp # Border Gateway Protocol -# Kirk Lougheed -ris 180/udp # Intergraph -ris 180/tcp # Intergraph -# Dave Buehmann -unify 181/udp # Unify -unify 181/tcp # Unify -# Mark Ainsley -audit 182/udp # Unisys Audit SITP -audit 182/tcp # Unisys Audit SITP -# Gil Greenbaum -ocbinder 183/udp # OCBinder -ocbinder 183/tcp # OCBinder -ocserver 184/udp # OCServer -ocserver 184/tcp # OCServer -# Jerrilynn Okamura <--none---> -remote-kis 185/udp # Remote-KIS -remote-kis 185/tcp # Remote-KIS -kis 186/udp # KIS Protocol -kis 186/tcp # KIS Protocol -# Ralph Droms -aci 187/udp # Application Communication Interface -aci 187/tcp # Application Communication Interface -# Rick Carlos -mumps 188/udp # Plus Five's MUMPS -mumps 188/tcp # Plus Five's MUMPS -# Hokey Stenn -qft 189/udp # Queued File Transport -qft 189/tcp # Queued File Transport -# Wayne Schroeder -gacp 190/udp # Gateway Access Control Protocol -gacp 190/tcp # Gateway Access Control Protocol -# C. Philip Wood -prospero 191/udp # Prospero Directory Service -prospero 191/tcp # Prospero Directory Service -# B. Clifford Neuman -osu-nms 192/udp # OSU Network Monitoring System -osu-nms 192/tcp # OSU Network Monitoring System -# Doug Karl -srmp 193/udp # Spider Remote Monitoring Protocol -srmp 193/tcp # Spider Remote Monitoring Protocol -# Ted J. Socolofsky -irc 194/udp # Internet Relay Chat Protocol -irc 194/tcp # Internet Relay Chat Protocol -# Jarkko Oikarinen -dn6-nlm-aud 195/udp # DNSIX Network Level Module Audit -dn6-nlm-aud 195/tcp # DNSIX Network Level Module Audit -dn6-smm-red 196/udp # DNSIX Session Mgt Module Audit Redir -dn6-smm-red 196/tcp # DNSIX Session Mgt Module Audit Redir -# Lawrence Lebahn -dls 197/udp # Directory Location Service -dls 197/tcp # Directory Location Service -dls-mon 198/udp # Directory Location Service Monitor -dls-mon 198/tcp # Directory Location Service Monitor -# Scott Bellew -smux 199/udp # SMUX -smux 199/tcp # SMUX -# Marshall Rose -src 200/udp # IBM System Resource Controller -src 200/tcp # IBM System Resource Controller -# Gerald McBrearty <---none---> -at-rtmp 201/udp # AppleTalk Routing Maintenance -at-rtmp 201/tcp # AppleTalk Routing Maintenance -at-nbp 202/udp # AppleTalk Name Binding -at-nbp 202/tcp # AppleTalk Name Binding -at-3 203/udp # AppleTalk Unused -at-3 203/tcp # AppleTalk Unused -at-echo 204/udp # AppleTalk Echo -at-echo 204/tcp # AppleTalk Echo -at-5 205/udp # AppleTalk Unused -at-5 205/tcp # AppleTalk Unused -at-zis 206/udp # AppleTalk Zone Information -at-zis 206/tcp # AppleTalk Zone Information -at-7 207/udp # AppleTalk Unused -at-7 207/tcp # AppleTalk Unused -at-8 208/udp # AppleTalk Unused -at-8 208/tcp # AppleTalk Unused -# Rob Chandhok -qmtp 209/udp # The Quick Mail Transfer Protocol -qmtp 209/tcp # The Quick Mail Transfer Protocol -# Dan Bernstein -z39.50 210/udp # ANSI Z39.50 -z39.50 210/tcp # ANSI Z39.50 -# Mark H. Needleman -914c/g 211/udp # Texas Instruments 914C/G Terminal -914c/g 211/tcp # Texas Instruments 914C/G Terminal -# Bill Harrell <---none---> -anet 212/udp # ATEXSSTR -anet 212/tcp # ATEXSSTR -# Jim Taylor -ipx 213/udp # IPX -ipx 213/tcp # IPX -# Don Provan -vmpwscs 214/udp # VM PWSCS -vmpwscs 214/tcp # VM PWSCS -# Dan Shia -softpc 215/udp # Insignia Solutions -softpc 215/tcp # Insignia Solutions -# Martyn Thomas <---none---> -CAIlic 216/udp # Computer Associates Int'l License Server -CAIlic 216/tcp # Computer Associates Int'l License Server -# Chuck Spitz -dbase 217/udp # dBASE Unix -dbase 217/tcp # dBASE Unix -# Don Gibson -# -mpp 218/udp # Netix Message Posting Protocol -mpp 218/tcp # Netix Message Posting Protocol -# Shannon Yeh -uarps 219/udp # Unisys ARPs -uarps 219/tcp # Unisys ARPs -# Ashok Marwaha <---none---> -imap3 220/udp # Interactive Mail Access Protocol v3 -imap3 220/tcp # Interactive Mail Access Protocol v3 -# James Rice -fln-spx 221/udp # Berkeley rlogind with SPX auth -fln-spx 221/tcp # Berkeley rlogind with SPX auth -rsh-spx 222/udp # Berkeley rshd with SPX auth -rsh-spx 222/tcp # Berkeley rshd with SPX auth -cdc 223/udp # Certificate Distribution Center -cdc 223/tcp # Certificate Distribution Center -# Kannan Alagappan -########### Possible Conflict of Port 222 with "Masqdialer"############## -### Contact for Masqdialer is Charles Wright ### -masqdialer 224/udp # masqdialer -masqdialer 224/tcp # masqdialer -# Charles Wright -# 225-241 Reserved -# Jon Postel -direct 242/udp # Direct -direct 242/tcp # Direct -# Herb Sutter -sur-meas 243/udp # Survey Measurement -sur-meas 243/tcp # Survey Measurement -# Dave Clark -inbusiness 244/udp # inbusiness -inbusiness 244/tcp # inbusiness -# Derrick Hisatake -link 245/udp # LINK -link 245/tcp # LINK -dsp3270 246/udp # Display Systems Protocol -dsp3270 246/tcp # Display Systems Protocol -# Weldon J. Showalter -subntbcst_tftp 247/udp # SUBNTBCST_TFTP -subntbcst_tftp 247/tcp # SUBNTBCST_TFTP -# John Fake -bhfhs 248/udp # bhfhs -bhfhs 248/tcp # bhfhs -# John Kelly -# 249-255 Reserved -# Jon Postel -rap 256/udp # RAP -rap 256/tcp # RAP -# J.S. Greenfield -set 257/udp # Secure Electronic Transaction -set 257/tcp # Secure Electronic Transaction -# Donald Eastlake -yak-chat 258/udp # Yak Winsock Personal Chat -yak-chat 258/tcp # Yak Winsock Personal Chat -# Brian Bandy -esro-gen 259/udp # Efficient Short Remote Operations -esro-gen 259/tcp # Efficient Short Remote Operations -# Mohsen Banan -openport 260/udp # Openport -openport 260/tcp # Openport -# John Marland -nsiiops 261/udp # IIOP Name Service over TLS/SSL -nsiiops 261/tcp # IIOP Name Service over TLS/SSL -# Jeff Stewart -arcisdms 262/udp # Arcisdms -arcisdms 262/tcp # Arcisdms -# Russell Crook (rmc@sni.ca> -hdap 263/udp # HDAP -hdap 263/tcp # HDAP -# Troy Gau -bgmp 264/udp # BGMP -bgmp 264/tcp # BGMP -# Dave Thaler -x-bone-ctl 265/udp # X-Bone CTL -x-bone-ctl 265/tcp # X-Bone CTL -# Joe Touch -sst 266/udp # SCSI on ST -sst 266/tcp # SCSI on ST -# Donald D. Woelz -td-service 267/udp # Tobit David Service Layer -td-service 267/tcp # Tobit David Service Layer -td-replica 268/udp # Tobit David Replica -td-replica 268/tcp # Tobit David Replica -# Franz-Josef Leuders -# 269-279 Unassigned -http-mgmt 280/udp # http-mgmt -http-mgmt 280/tcp # http-mgmt -# Adrian Pell -# -personal-link 281/udp # Personal Link -personal-link 281/tcp # Personal Link -# Dan Cummings -cableport-ax 282/udp # Cable Port A/X -cableport-ax 282/tcp # Cable Port A/X -# Craig Langfahl -rescap 283/udp # rescap -rescap 283/tcp # rescap -# Paul Hoffman -corerjd 284/udp # corerjd -corerjd 284/tcp # corerjd -# Chris Thornhill -# 285 Unassigned -fxp-1 286/udp # FXP-1 -fxp-1 286/tcp # FXP-1 -# James Darnall -k-block 287/udp # K-BLOCK -k-block 287/tcp # K-BLOCK -# Simon P Jackson -# 288-307 Unassigned -novastorbakcup 308/udp # Novastor Backup -novastorbakcup 308/tcp # Novastor Backup -# Brian Dickman -entrusttime 309/udp # EntrustTime -entrusttime 309/tcp # EntrustTime -# Peter Whittaker -bhmds 310/udp # bhmds -bhmds 310/tcp # bhmds -# John Kelly -asip-webadmin 311/udp # AppleShare IP WebAdmin -asip-webadmin 311/tcp # AppleShare IP WebAdmin -# Ann Huang -vslmp 312/udp # VSLMP -vslmp 312/tcp # VSLMP -# Gerben Wierda -magenta-logic 313/udp # Magenta Logic -magenta-logic 313/tcp # Magenta Logic -# Karl Rousseau -opalis-robot 314/udp # Opalis Robot -opalis-robot 314/tcp # Opalis Robot -# Laurent Domenech, Opalis -dpsi 315/udp # DPSI -dpsi 315/tcp # DPSI -# Tony Scamurra -decauth 316/udp # decAuth -decauth 316/tcp # decAuth -# Michael Agishtein -zannet 317/udp # Zannet -zannet 317/tcp # Zannet -# Zan Oliphant -pkix-timestamp 318/udp # PKIX TimeStamp -pkix-timestamp 318/tcp # PKIX TimeStamp -# Robert Zuccherato -ptp-event 319/udp # PTP Event -ptp-event 319/tcp # PTP Event -ptp-general 320/udp # PTP General -ptp-general 320/tcp # PTP General -# John Eidson -pip 321/udp # PIP -pip 321/tcp # PIP -# Gordon Mohr -rtsps 322/udp # RTSPS -rtsps 322/tcp # RTSPS -# Anders Klemets -# 323-332 Unassigned -texar 333/udp # Texar Security Port -texar 333/tcp # Texar Security Port -# Eugen Bacic -# 334-343 Unassigned -pdap 344/udp # Prospero Data Access Protocol -pdap 344/tcp # Prospero Data Access Protocol -# B. Clifford Neuman -pawserv 345/udp # Perf Analysis Workbench -pawserv 345/tcp # Perf Analysis Workbench -zserv 346/udp # Zebra server -zserv 346/tcp # Zebra server -fatserv 347/udp # Fatmen Server -fatserv 347/tcp # Fatmen Server -csi-sgwp 348/udp # Cabletron Management Protocol -csi-sgwp 348/tcp # Cabletron Management Protocol -mftp 349/udp # mftp -mftp 349/tcp # mftp -# Dave Feinleib -matip-type-a 350/udp # MATIP Type A -matip-type-a 350/tcp # MATIP Type A -matip-type-b 351/udp # MATIP Type B -matip-type-b 351/tcp # MATIP Type B -# Alain Robert -# The following entry records an unassigned but widespread use -bhoetty 351/udp # bhoetty -bhoetty 351/tcp # bhoetty (added 5/21/97) -# John Kelly -dtag-ste-sb 352/udp # DTAG -dtag-ste-sb 352/tcp # DTAG (assigned long ago) -# Ruediger Wald -# The following entry records an unassigned but widespread use -bhoedap4 352/udp # bhoedap4 -bhoedap4 352/tcp # bhoedap4 (added 5/21/97) -# John Kelly -ndsauth 353/udp # NDSAUTH -ndsauth 353/tcp # NDSAUTH -# Jayakumar Ramalingam -bh611 354/udp # bh611 -bh611 354/tcp # bh611 -# John Kelly -datex-asn 355/udp # DATEX-ASN -datex-asn 355/tcp # DATEX-ASN -# Kenneth Vaughn -cloanto-net-1 356/udp # Cloanto Net 1 -cloanto-net-1 356/tcp # Cloanto Net 1 -# Michael Battilana -bhevent 357/udp # bhevent -bhevent 357/tcp # bhevent -# John Kelly -shrinkwrap 358/udp # Shrinkwrap -shrinkwrap 358/tcp # Shrinkwrap -# Bill Simpson -nsrmp 359/udp # Network Security Risk Management Protocol -nsrmp 359/tcp # Network Security Risk Management Protocol -# Eric Jacksch -scoi2odialog 360/udp # scoi2odialog -scoi2odialog 360/tcp # scoi2odialog -# Keith Petley -semantix 361/udp # Semantix -semantix 361/tcp # Semantix -# Semantix -srssend 362/udp # SRS Send -srssend 362/tcp # SRS Send -# Curt Mayer -rsvp_tunnel 363/udp # RSVP Tunnel -rsvp_tunnel 363/tcp # RSVP Tunnel -# Andreas Terzis -aurora-cmgr 364/udp # Aurora CMGR -aurora-cmgr 364/tcp # Aurora CMGR -# Philip Budne -dtk 365/udp # DTK -dtk 365/tcp # DTK -# Fred Cohen -odmr 366/udp # ODMR -odmr 366/tcp # ODMR -# Randall Gellens -mortgageware 367/udp # MortgageWare -mortgageware 367/tcp # MortgageWare -# Ole Hellevik -qbikgdp 368/udp # QbikGDP -qbikgdp 368/tcp # QbikGDP -# Adrien de Croy -rpc2portmap 369/udp # rpc2portmap -rpc2portmap 369/tcp # rpc2portmap -codaauth2 370/udp # codaauth2 -codaauth2 370/tcp # codaauth2 -# Robert Watson -clearcase 371/udp # Clearcase -clearcase 371/tcp # Clearcase -# Dave LeBlang -ulistproc 372/udp # ListProcessor -ulistproc 372/tcp # ListProcessor -# Anastasios Kotsikonas -legent-1 373/udp # Legent Corporation -legent-1 373/tcp # Legent Corporation -legent-2 374/udp # Legent Corporation -legent-2 374/tcp # Legent Corporation -# Keith Boyce <---none---> -hassle 375/udp # Hassle -hassle 375/tcp # Hassle -# Reinhard Doelz -nip 376/udp # Amiga Envoy Network Inquiry Proto -nip 376/tcp # Amiga Envoy Network Inquiry Proto -# Heinz Wrobel -tnETOS 377/udp # NEC Corporation -tnETOS 377/tcp # NEC Corporation -dsETOS 378/udp # NEC Corporation -dsETOS 378/tcp # NEC Corporation -# Tomoo Fujita -is99c 379/udp # TIA/EIA/IS-99 modem client -is99c 379/tcp # TIA/EIA/IS-99 modem client -is99s 380/udp # TIA/EIA/IS-99 modem server -is99s 380/tcp # TIA/EIA/IS-99 modem server -# Frank Quick -hp-collector 381/udp # hp performance data collector -hp-collector 381/tcp # hp performance data collector -hp-managed-node 382/udp # hp performance data managed node -hp-managed-node 382/tcp # hp performance data managed node -hp-alarm-mgr 383/udp # hp performance data alarm manager -hp-alarm-mgr 383/tcp # hp performance data alarm manager -# Frank Blakely -arns 384/udp # A Remote Network Server System -arns 384/tcp # A Remote Network Server System -# David Hornsby -ibm-app 385/udp # IBM Application -ibm-app 385/tcp # IBM Application -# Lisa Tomita <---none---> -asa 386/udp # ASA Message Router Object Def. -asa 386/tcp # ASA Message Router Object Def. -# Steve Laitinen -aurp 387/udp # Appletalk Update-Based Routing Pro. -aurp 387/tcp # Appletalk Update-Based Routing Pro. -# Chris Ranch -unidata-ldm 388/udp # Unidata LDM -unidata-ldm 388/tcp # Unidata LDM -# Glenn Davis -ldap 389/udp # Lightweight Directory Access Protocol -ldap 389/tcp # Lightweight Directory Access Protocol -# Tim Howes -uis 390/udp # UIS -uis 390/tcp # UIS -# Ed Barron <---none---> -synotics-relay 391/udp # SynOptics SNMP Relay Port -synotics-relay 391/tcp # SynOptics SNMP Relay Port -synotics-broker 392/udp # SynOptics Port Broker Port -synotics-broker 392/tcp # SynOptics Port Broker Port -# Illan Raab -meta5 393/udp # Meta5 -meta5 393/tcp # Meta5 -# Jim Kanzler -embl-ndt 394/udp # EMBL Nucleic Data Transfer -embl-ndt 394/tcp # EMBL Nucleic Data Transfer -# Peter Gad -netcp 395/udp # NETscout Control Protocol -netcp 395/tcp # NETscout Control Protocol -# Anil Singhal <---none---> -netware-ip 396/udp # Novell Netware over IP -netware-ip 396/tcp # Novell Netware over IP -mptn 397/udp # Multi Protocol Trans. Net. -mptn 397/tcp # Multi Protocol Trans. Net. -# Soumitra Sarkar -kryptolan 398/udp # Kryptolan -kryptolan 398/tcp # Kryptolan -# Peter de Laval -iso-tsap-c2 399/udp # ISO Transport Class 2 Non-Control over UDP -iso-tsap-c2 399/tcp # ISO Transport Class 2 Non-Control over TCP -# Yanick Pouffary -work-sol 400/udp # Workstation Solutions -work-sol 400/tcp # Workstation Solutions -# Jim Ward -ups 401/udp # Uninterruptible Power Supply -ups 401/tcp # Uninterruptible Power Supply -# Charles Bennett -genie 402/udp # Genie Protocol -genie 402/tcp # Genie Protocol -# Mark Hankin <---none---> -decap 403/udp # decap -decap 403/tcp # decap -nced 404/udp # nced -nced 404/tcp # nced -ncld 405/udp # ncld -ncld 405/tcp # ncld -# Richard Jones <---none---> -imsp 406/udp # Interactive Mail Support Protocol -imsp 406/tcp # Interactive Mail Support Protocol -# John Myers -timbuktu 407/udp # Timbuktu -timbuktu 407/tcp # Timbuktu -# Marc Epard -prm-sm 408/udp # Prospero Resource Manager Sys. Man. -prm-sm 408/tcp # Prospero Resource Manager Sys. Man. -prm-nm 409/udp # Prospero Resource Manager Node Man. -prm-nm 409/tcp # Prospero Resource Manager Node Man. -# B. Clifford Neuman -decladebug 410/udp # DECLadebug Remote Debug Protocol -decladebug 410/tcp # DECLadebug Remote Debug Protocol -# Anthony Berent -rmt 411/udp # Remote MT Protocol -rmt 411/tcp # Remote MT Protocol -# Peter Eriksson -synoptics-trap 412/udp # Trap Convention Port -synoptics-trap 412/tcp # Trap Convention Port -# Illan Raab -smsp 413/udp # Storage Management Services Protocol -smsp 413/tcp # Storage Management Services Protocol -# Murthy Srinivas -infoseek 414/udp # InfoSeek -infoseek 414/tcp # InfoSeek -# Steve Kirsch -bnet 415/udp # BNet -bnet 415/tcp # BNet -# Jim Mertz -silverplatter 416/udp # Silverplatter -silverplatter 416/tcp # Silverplatter -# Peter Ciuffetti -onmux 417/udp # Onmux -onmux 417/tcp # Onmux -# Stephen Hanna -hyper-g 418/udp # Hyper-G -hyper-g 418/tcp # Hyper-G -# Frank Kappe -ariel1 419/udp # Ariel 1 -ariel1 419/tcp # Ariel 1 -# Joel Karafin -smpte 420/udp # SMPTE -smpte 420/tcp # SMPTE -# Si Becker <71362.22@CompuServe.COM> -ariel2 421/udp # Ariel 2 -ariel2 421/tcp # Ariel 2 -ariel3 422/udp # Ariel 3 -ariel3 422/tcp # Ariel 3 -# Joel Karafin -opc-job-start 423/udp # IBM Operations Planning and Control Start -opc-job-start 423/tcp # IBM Operations Planning and Control Start -opc-job-track 424/udp # IBM Operations Planning and Control Track -opc-job-track 424/tcp # IBM Operations Planning and Control Track -# Conny Larsson -icad-el 425/udp # ICAD -icad-el 425/tcp # ICAD -# Larry Stone -smartsdp 426/udp # smartsdp -smartsdp 426/tcp # smartsdp -# Alexander Dupuy -svrloc 427/udp # Server Location -svrloc 427/tcp # Server Location -# -ocs_cmu 428/udp # OCS_CMU -ocs_cmu 428/tcp # OCS_CMU -ocs_amu 429/udp # OCS_AMU -ocs_amu 429/tcp # OCS_AMU -# Florence Wyman -utmpsd 430/udp # UTMPSD -utmpsd 430/tcp # UTMPSD -utmpcd 431/udp # UTMPCD -utmpcd 431/tcp # UTMPCD -iasd 432/udp # IASD -iasd 432/tcp # IASD -# Nir Baroz -nnsp 433/udp # NNSP -nnsp 433/tcp # NNSP -# Rob Robertson -mobileip-agent 434/udp # MobileIP-Agent -mobileip-agent 434/tcp # MobileIP-Agent -mobilip-mn 435/udp # MobilIP-MN -mobilip-mn 435/tcp # MobilIP-MN -# Kannan Alagappan -dna-cml 436/udp # DNA-CML -dna-cml 436/tcp # DNA-CML -# Dan Flowers -comscm 437/udp # comscm -comscm 437/tcp # comscm -# Jim Teague -dsfgw 438/udp # dsfgw -dsfgw 438/tcp # dsfgw -# Andy McKeen -dasp 439/udp # dasp tommy@inlab.m.eunet.de -dasp 439/tcp # dasp Thomas Obermair -# Thomas Obermair -sgcp 440/udp # sgcp -sgcp 440/tcp # sgcp -# Marshall Rose -decvms-sysmgt 441/udp # decvms-sysmgt -decvms-sysmgt 441/tcp # decvms-sysmgt -# Lee Barton -cvc_hostd 442/udp # cvc_hostd -cvc_hostd 442/tcp # cvc_hostd -# Bill Davidson -https 443/udp # http protocol over TLS/SSL -https 443/tcp # http protocol over TLS/SSL -# Kipp E.B. Hickman -snpp 444/udp # Simple Network Paging Protocol -snpp 444/tcp # Simple Network Paging Protocol -# [RFC1568] -microsoft-ds 445/udp # Microsoft-DS -microsoft-ds 445/tcp # Microsoft-DS -# Pradeep Bahl -ddm-rdb 446/udp # DDM-RDB -ddm-rdb 446/tcp # DDM-RDB -ddm-dfm 447/udp # DDM-RFM -ddm-dfm 447/tcp # DDM-RFM -# Jan David Fisher -ddm-ssl 448/udp # DDM-SSL -ddm-ssl 448/tcp # DDM-SSL -# Steve Ritland -as-servermap 449/udp # AS Server Mapper -as-servermap 449/tcp # AS Server Mapper -# Barbara Foss -tserver 450/udp # Computer Supported Telecomunication Applications -tserver 450/tcp # Computer Supported Telecomunication Applications -# Harvey S. Schultz -sfs-smp-net 451/udp # Cray Network Semaphore server -sfs-smp-net 451/tcp # Cray Network Semaphore server -sfs-config 452/udp # Cray SFS config server -sfs-config 452/tcp # Cray SFS config server -# Walter Poxon -creativeserver 453/udp # CreativeServer -creativeserver 453/tcp # CreativeServer -contentserver 454/udp # ContentServer -contentserver 454/tcp # ContentServer -creativepartnr 455/udp # CreativePartnr -creativepartnr 455/tcp # CreativePartnr -# Jesus Ortiz -macon-udp 456/udp # macon-udp -macon-tcp 456/tcp # macon-tcp -# Yoshinobu Inoue -# -scohelp 457/udp # scohelp -scohelp 457/tcp # scohelp -# Faith Zack -appleqtc 458/udp # apple quick time -appleqtc 458/tcp # apple quick time -# Murali Ranganathan -# -ampr-rcmd 459/udp # ampr-rcmd -ampr-rcmd 459/tcp # ampr-rcmd -# Rob Janssen -skronk 460/udp # skronk -skronk 460/tcp # skronk -# Henry Strickland -datasurfsrv 461/udp # DataRampSrv -datasurfsrv 461/tcp # DataRampSrv -datasurfsrvsec 462/udp # DataRampSrvSec -datasurfsrvsec 462/tcp # DataRampSrvSec -# Diane Downie -alpes 463/udp # alpes -alpes 463/tcp # alpes -# Alain Durand -kpasswd 464/udp # kpasswd -kpasswd 464/tcp # kpasswd -# Theodore Ts'o -igmpv3lite 465/udp # IGMP over UDP for SSM -urd 465/tcp # URL Rendesvous Directory for SSM -# Toerless Eckert -digital-vrc 466/udp # digital-vrc -digital-vrc 466/tcp # digital-vrc -# Peter Higginson -mylex-mapd 467/udp # mylex-mapd -mylex-mapd 467/tcp # mylex-mapd -# Gary Lewis -photuris 468/udp # proturis -photuris 468/tcp # proturis -# Bill Simpson -rcp 469/udp # Radio Control Protocol -rcp 469/tcp # Radio Control Protocol -# Jim Jennings +1-708-538-7241 -scx-proxy 470/udp # scx-proxy -scx-proxy 470/tcp # scx-proxy -# Scott Narveson -mondex 471/udp # Mondex -mondex 471/tcp # Mondex -# Bill Reding -ljk-login 472/udp # ljk-login -ljk-login 472/tcp # ljk-login -# LJK Software, Cambridge, Massachusetts -# -hybrid-pop 473/udp # hybrid-pop -hybrid-pop 473/tcp # hybrid-pop -# Rami Rubin -tn-tl-w2 474/udp # tn-tl-w2 -tn-tl-w1 474/tcp # tn-tl-w1 -# Ed Kress -tcpnethaspsrv 475/udp # tcpnethaspsrv -tcpnethaspsrv 475/tcp # tcpnethaspsrv -# Charlie Hava -tn-tl-fd1 476/udp # tn-tl-fd1 -tn-tl-fd1 476/tcp # tn-tl-fd1 -# Ed Kress -ss7ns 477/udp # ss7ns -ss7ns 477/tcp # ss7ns -# Jean-Michel URSCH -spsc 478/udp # spsc -spsc 478/tcp # spsc -# Mike Rieker -iafserver 479/udp # iafserver -iafserver 479/tcp # iafserver -iafdbase 480/udp # iafdbase -iafdbase 480/tcp # iafdbase -# ricky@solect.com -ph 481/udp # Ph service -ph 481/tcp # Ph service -# Roland Hedberg -bgs-nsi 482/udp # bgs-nsi -bgs-nsi 482/tcp # bgs-nsi -# Jon Saperia -ulpnet 483/udp # ulpnet -ulpnet 483/tcp # ulpnet -# Kevin Mooney -integra-sme 484/udp # Integra Software Management Environment -integra-sme 484/tcp # Integra Software Management Environment -# Randall Dow -powerburst 485/udp # Air Soft Power Burst -powerburst 485/tcp # Air Soft Power Burst -# -avian 486/udp # avian -avian 486/tcp # avian -# Robert Ullmann -# -saft 487/udp # saft Simple Asynchronous File Transfer -saft 487/tcp # saft Simple Asynchronous File Transfer -# Ulli Horlacher -gss-http 488/udp # gss-http -gss-http 488/tcp # gss-http -# Doug Rosenthal -nest-protocol 489/udp # nest-protocol -nest-protocol 489/tcp # nest-protocol -# Gilles Gameiro -micom-pfs 490/udp # micom-pfs -micom-pfs 490/tcp # micom-pfs -# David Misunas -go-login 491/udp # go-login -go-login 491/tcp # go-login -# Troy Morrison -ticf-1 492/udp # Transport Independent Convergence for FNA -ticf-1 492/tcp # Transport Independent Convergence for FNA -ticf-2 493/udp # Transport Independent Convergence for FNA -ticf-2 493/tcp # Transport Independent Convergence for FNA -# Mamoru Ito -pov-ray 494/udp # POV-Ray -pov-ray 494/tcp # POV-Ray -# POV-Team Co-ordinator -# -intecourier 495/udp # intecourier -intecourier 495/tcp # intecourier -# Steve Favor -pim-rp-disc 496/udp # PIM-RP-DISC -pim-rp-disc 496/tcp # PIM-RP-DISC -# Dino Farinacci -dantz 497/udp # dantz -dantz 497/tcp # dantz -# Richard Zulch -siam 498/udp # siam -siam 498/tcp # siam -# Philippe Gilbert -iso-ill 499/udp # ISO ILL Protocol -iso-ill 499/tcp # ISO ILL Protocol -# Mark H. Needleman -isakmp 500/udp # isakmp -isakmp 500/tcp # isakmp -# Mark Schertler -stmf 501/udp # STMF -stmf 501/tcp # STMF -# Alan Ungar -asa-appl-proto 502/udp # asa-appl-proto -asa-appl-proto 502/tcp # asa-appl-proto -# Dennis Dube -intrinsa 503/udp # Intrinsa -intrinsa 503/tcp # Intrinsa -# Robert Ford -citadel 504/udp # citadel -citadel 504/tcp # citadel -# Art Cancro -mailbox-lm 505/udp # mailbox-lm -mailbox-lm 505/tcp # mailbox-lm -# Beverly Moody -ohimsrv 506/udp # ohimsrv -ohimsrv 506/tcp # ohimsrv -# Scott Powell -crs 507/udp # crs -crs 507/tcp # crs -# Brad Wright -xvttp 508/udp # xvttp -xvttp 508/tcp # xvttp -# Keith J. Alphonso -snare 509/udp # snare -snare 509/tcp # snare -# Dennis Batchelder -fcp 510/udp # FirstClass Protocol -fcp 510/tcp # FirstClass Protocol -# Mike Marshburn -passgo 511/udp # PassGo -passgo 511/tcp # PassGo -# John Rainford -exec 512/tcp # remote process execution; -# authentication performed using -# passwords and UNIX login names -comsat 512/udp biff # -# of new mail received; currently -# receives messages only from -# processes on the same machine -login 513/tcp # remote login a la telnet; -# automatic authentication performed -# based on priviledged port numbers -# and distributed data bases which -# identify "authentication domains" -who 513/udp # maintains data bases showing who's -# logged in to machines on a local -# net and the load average of the -# machine -shell 514/tcp # cmd -# like exec, but automatic authentication -# is performed as for login server -syslog 514/udp # -printer 515/udp # spooler -printer 515/tcp # spooler -videotex 516/udp # videotex -videotex 516/tcp # videotex -# Daniel Mavrakis -talk 517/tcp # like tenex link, but across -# machine - unfortunately, doesn't -# use link protocol (this is actually -# just a rendezvous port from which a -# tcp connection is established) -talk 517/udp # like tenex link, but across -# machine - unfortunately, doesn't -# use link protocol (this is actually -# just a rendezvous port from which a -# tcp connection is established) -ntalk 518/udp # -ntalk 518/tcp # -utime 519/udp # unixtime -utime 519/tcp # unixtime -router 520/udp # local routing process (on site); -efs 520/tcp # extended file name server -# uses variant of Xerox NS routing -# information protocol - RIP -ripng 521/udp # ripng -ripng 521/tcp # ripng -# Robert E. Minnear -ulp 522/udp # ULP -ulp 522/tcp # ULP -# Max Morris -ibm-db2 523/udp # IBM-DB2 -ibm-db2 523/tcp # IBM-DB2 -# Peter Pau -ncp 524/udp # NCP -ncp 524/tcp # NCP -# Don Provan -timed 525/udp # timeserver -timed 525/tcp # timeserver -tempo 526/udp # newdate -tempo 526/tcp # newdate -# Unknown -stx 527/udp # Stock IXChange -stx 527/tcp # Stock IXChange -custix 528/udp # Customer IXChange -custix 528/tcp # Customer IXChange -# Ferdi Ladeira -irc-serv 529/udp # IRC-SERV -irc-serv 529/tcp # IRC-SERV -# Brian Tackett -courier 530/udp # rpc -courier 530/tcp # rpc -conference 531/udp # chat -conference 531/tcp # chat -netnews 532/udp # readnews -netnews 532/tcp # readnews -netwall 533/udp # for emergency broadcasts -netwall 533/tcp # for emergency broadcasts -mm-admin 534/udp # MegaMedia Admin -mm-admin 534/tcp # MegaMedia Admin -# Andreas Heidemann -iiop 535/udp # iiop -iiop 535/tcp # iiop -# Jeff M.Michaud -opalis-rdv 536/udp # opalis-rdv -opalis-rdv 536/tcp # opalis-rdv -# Laurent Domenech -nmsp 537/udp # Networked Media Streaming Protocol -nmsp 537/tcp # Networked Media Streaming Protocol -# Paul Santinelli Jr. -gdomap 538/udp # gdomap -gdomap 538/tcp # gdomap -# Richard Frith-Macdonald -apertus-ldp 539/udp # Apertus Technologies Load Determination -apertus-ldp 539/tcp # Apertus Technologies Load Determination -uucp 540/udp # uucpd -uucp 540/tcp # uucpd -uucp-rlogin 541/udp # uucp-rlogin -uucp-rlogin 541/tcp # uucp-rlogin -# Stuart Lynne -commerce 542/udp # commerce -commerce 542/tcp # commerce -# Randy Epstein -klogin 543/udp # -klogin 543/tcp # -kshell 544/udp # krcmd -kshell 544/tcp # krcmd -appleqtcsrvr 545/udp # appleqtcsrvr -appleqtcsrvr 545/tcp # appleqtcsrvr -# Murali Ranganathan -# -dhcpv6-client 546/udp # DHCPv6 Client -dhcpv6-client 546/tcp # DHCPv6 Client -dhcpv6-server 547/udp # DHCPv6 Server -dhcpv6-server 547/tcp # DHCPv6 Server -# Jim Bound -afpovertcp 548/udp # AFP over TCP -afpovertcp 548/tcp # AFP over TCP -# Leland Wallace -idfp 549/udp # IDFP -idfp 549/tcp # IDFP -# Ramana Kovi -new-rwho 550/udp # new-who -new-rwho 550/tcp # new-who -cybercash 551/udp # cybercash -cybercash 551/tcp # cybercash -# Donald E. Eastlake 3rd -devshr-nts 552/udp # DeviceShare -devshr-nts 552/tcp # DeviceShare -# Benjamin Rosenberg -pirp 553/udp # pirp -pirp 553/tcp # pirp -# D. J. Bernstein -rtsp 554/udp # Real Time Stream Control Protocol -rtsp 554/tcp # Real Time Stream Control Protocol -# Rob Lanphier -dsf 555/udp # -dsf 555/tcp # -remotefs 556/udp # rfs server -remotefs 556/tcp # rfs server -openvms-sysipc 557/udp # openvms-sysipc -openvms-sysipc 557/tcp # openvms-sysipc -# Alan Potter -sdnskmp 558/udp # SDNSKMP -sdnskmp 558/tcp # SDNSKMP -teedtap 559/udp # TEEDTAP -teedtap 559/tcp # TEEDTAP -# Mort Hoffman -rmonitor 560/udp # rmonitord -rmonitor 560/tcp # rmonitord -monitor 561/udp # -monitor 561/tcp # -chshell 562/udp # chcmd -chshell 562/tcp # chcmd -nntps 563/udp # nntp protocol over TLS/SSL (was snntp) -nntps 563/tcp # nntp protocol over TLS/SSL (was snntp) -# Kipp E.B. Hickman -9pfs 564/udp # plan 9 file service -9pfs 564/tcp # plan 9 file service -whoami 565/udp # whoami -whoami 565/tcp # whoami -streettalk 566/udp # streettalk -streettalk 566/tcp # streettalk -banyan-rpc 567/udp # banyan-rpc -banyan-rpc 567/tcp # banyan-rpc -# Tom Lemaire -ms-shuttle 568/udp # microsoft shuttle -ms-shuttle 568/tcp # microsoft shuttle -# Rudolph Balaz -ms-rome 569/udp # microsoft rome -ms-rome 569/tcp # microsoft rome -# Rudolph Balaz -meter 570/udp # demon -meter 570/tcp # demon -meter 571/udp # udemon -meter 571/tcp # udemon -sonar 572/udp # sonar -sonar 572/tcp # sonar -# Keith Moore -banyan-vip 573/udp # banyan-vip -banyan-vip 573/tcp # banyan-vip -# Denis Leclerc -ftp-agent 574/udp # FTP Software Agent System -ftp-agent 574/tcp # FTP Software Agent System -# Michael S. Greenberg -vemmi 575/udp # VEMMI -vemmi 575/tcp # VEMMI -# Daniel Mavrakis -ipcd 576/udp # ipcd -ipcd 576/tcp # ipcd -vnas 577/udp # vnas -vnas 577/tcp # vnas -ipdd 578/udp # ipdd -ipdd 578/tcp # ipdd -# Jay Farhat -decbsrv 579/udp # decbsrv -decbsrv 579/tcp # decbsrv -# Rudi Martin -sntp-heartbeat 580/udp # SNTP HEARTBEAT -sntp-heartbeat 580/tcp # SNTP HEARTBEAT -# Louis Mamakos -bdp 581/udp # Bundle Discovery Protocol -bdp 581/tcp # Bundle Discovery Protocol -# Gary Malkin -scc-security 582/udp # SCC Security -scc-security 582/tcp # SCC Security -# Prashant Dholakia -philips-vc 583/udp # Philips Video-Conferencing -philips-vc 583/tcp # Philips Video-Conferencing -# Janna Chang -keyserver 584/udp # Key Server -keyserver 584/tcp # Key Server -# Gary Howland -imap4-ssl 585/udp # IMAP4+SSL (use 993 instead) -imap4-ssl 585/tcp # IMAP4+SSL (use 993 instead) -# Terry Gray -# Use of 585 is not recommended, use 993 instead -password-chg 586/udp # Password Change -password-chg 586/tcp # Password Change -submission 587/udp # Submission -submission 587/tcp # Submission -# Randy Gellens -cal 588/udp # CAL -cal 588/tcp # CAL -# Myron Hattig -eyelink 589/udp # EyeLink -eyelink 589/tcp # EyeLink -# Dave Stampe -tns-cml 590/udp # TNS CML -tns-cml 590/tcp # TNS CML -# Jerome Albin -http-alt 591/udp # FileMaker, Inc. - HTTP Alternate (see Port 80) -http-alt 591/tcp # FileMaker, Inc. - HTTP Alternate (see Port 80) -# Clay Maeckel -eudora-set 592/udp # Eudora Set -eudora-set 592/tcp # Eudora Set -# Randall Gellens -http-rpc-epmap 593/udp # HTTP RPC Ep Map -http-rpc-epmap 593/tcp # HTTP RPC Ep Map -# Edward Reus -tpip 594/udp # TPIP -tpip 594/tcp # TPIP -# Brad Spear -cab-protocol 595/udp # CAB Protocol -cab-protocol 595/tcp # CAB Protocol -# Winston Hetherington -smsd 596/udp # SMSD -smsd 596/tcp # SMSD -# Wayne Barlow -ptcnameservice 597/udp # PTC Name Service -ptcnameservice 597/tcp # PTC Name Service -# Yuri Machkasov -sco-websrvrmg3 598/udp # SCO Web Server Manager 3 -sco-websrvrmg3 598/tcp # SCO Web Server Manager 3 -# Simon Baldwin -acp 599/udp # Aeolon Core Protocol -acp 599/tcp # Aeolon Core Protocol -# Michael Alyn Miller -ipcserver 600/udp # Sun IPC server -ipcserver 600/tcp # Sun IPC server -# Bill Schiefelbein -syslog-conn 601/udp # Reliable Syslog Service -syslog-conn 601/tcp # Reliable Syslog Service -# RFC 3195 -xmlrpc-beep 602/udp # XML-RPC over BEEP -xmlrpc-beep 602/tcp # XML-RPC over BEEP -# RFC3529 March 2003 -idxp 603/udp # IDXP -idxp 603/tcp # IDXP -# RFC-ietf-idwg-beep-idxp-07.txt -tunnel 604/udp # TUNNEL -tunnel 604/tcp # TUNNEL -# RFC-ietf-idwg-beep-tunnel-05.txt -soap-beep 605/udp # SOAP over BEEP -soap-beep 605/tcp # SOAP over BEEP -# RFC3288 April 2002 -urm 606/udp # Cray Unified Resource Manager -urm 606/tcp # Cray Unified Resource Manager -nqs 607/udp # nqs -nqs 607/tcp # nqs -# Bill Schiefelbein -sift-uft 608/udp # Sender-Initiated/Unsolicited File Transfer -sift-uft 608/tcp # Sender-Initiated/Unsolicited File Transfer -# Rick Troth -npmp-trap 609/udp # npmp-trap -npmp-trap 609/tcp # npmp-trap -npmp-local 610/udp # npmp-local -npmp-local 610/tcp # npmp-local -npmp-gui 611/udp # npmp-gui -npmp-gui 611/tcp # npmp-gui -# John Barnes -hmmp-ind 612/udp # HMMP Indication -hmmp-ind 612/tcp # HMMP Indication -hmmp-op 613/udp # HMMP Operation -hmmp-op 613/tcp # HMMP Operation -# Andrew Sinclair -sshell 614/udp # SSLshell -sshell 614/tcp # SSLshell -# Simon J. Gerraty -sco-inetmgr 615/udp # Internet Configuration Manager -sco-inetmgr 615/tcp # Internet Configuration Manager -sco-sysmgr 616/udp # SCO System Administration Server -sco-sysmgr 616/tcp # SCO System Administration Server -sco-dtmgr 617/udp # SCO Desktop Administration Server -sco-dtmgr 617/tcp # SCO Desktop Administration Server -# Christopher Durham -dei-icda 618/udp # DEI-ICDA -dei-icda 618/tcp # DEI-ICDA -# David Turner -compaq-evm 619/udp # Compaq EVM -compaq-evm 619/tcp # Compaq EVM -# Jem Treadwell -sco-websrvrmgr 620/udp # SCO WebServer Manager -sco-websrvrmgr 620/tcp # SCO WebServer Manager -# Christopher Durham -escp-ip 621/udp # ESCP -escp-ip 621/tcp # ESCP -# Lai Zit Seng -collaborator 622/udp # Collaborator -collaborator 622/tcp # Collaborator -# Johnson Davis -asf-rmcp 623/udp # ASF Remote Management and Control Protocol -asf-rmcp 623/tcp # ASF Remote Management and Control Protocol -# Carl First -cryptoadmin 624/udp # Crypto Admin -cryptoadmin 624/tcp # Crypto Admin -# Tony Walker -dec_dlm 625/udp # DEC DLM -dec_dlm 625/tcp # DEC DLM -# Rudi Martin -asia 626/udp # ASIA -asia 626/tcp # ASIA -# Michael Dasenbrock -passgo-tivoli 627/udp # PassGo Tivoli -passgo-tivoli 627/tcp # PassGo Tivoli -# Chris Hall -qmqp 628/udp # QMQP -qmqp 628/tcp # QMQP -# Dan Bernstein -3com-amp3 629/udp # 3Com AMP3 -3com-amp3 629/tcp # 3Com AMP3 -# Prakash Banthia -rda 630/udp # RDA -rda 630/tcp # RDA -# John Hadjioannou -ipp 631/udp # IPP (Internet Printing Protocol) -ipp 631/tcp # IPP (Internet Printing Protocol) -# Carl-Uno Manros -bmpp 632/udp # bmpp -bmpp 632/tcp # bmpp -# Troy Rollo -servstat 633/udp # Service Status update (Sterling Software) -servstat 633/tcp # Service Status update (Sterling Software) -# Greg Rose -ginad 634/udp # ginad -ginad 634/tcp # ginad -# Mark Crother -rlzdbase 635/udp # RLZ DBase -rlzdbase 635/tcp # RLZ DBase -# Michael Ginn -ldaps 636/udp # ldap protocol over TLS/SSL (was sldap) -ldaps 636/tcp # ldap protocol over TLS/SSL (was sldap) -# Pat Richard -lanserver 637/udp # lanserver -lanserver 637/tcp # lanserver -# Chris Larsson -mcns-sec 638/udp # mcns-sec -mcns-sec 638/tcp # mcns-sec -# Kaz Ozawa -msdp 639/udp # MSDP -msdp 639/tcp # MSDP -# Dino Farinacci -entrust-sps 640/udp # entrust-sps -entrust-sps 640/tcp # entrust-sps -# Marek Buchler -repcmd 641/udp # repcmd -repcmd 641/tcp # repcmd -# Scott Dale -esro-emsdp 642/udp # ESRO-EMSDP V1.3 -esro-emsdp 642/tcp # ESRO-EMSDP V1.3 -# Mohsen Banan -sanity 643/udp # SANity -sanity 643/tcp # SANity -# Peter Viscarola -dwr 644/udp # dwr -dwr 644/tcp # dwr -# Bill Fenner -pssc 645/udp # PSSC -pssc 645/tcp # PSSC -# Egon Meier-Engelen -ldp 646/udp # LDP -ldp 646/tcp # LDP -# Bob Thomas -dhcp-failover 647/udp # DHCP Failover -dhcp-failover 647/tcp # DHCP Failover -# Bernard Volz -rrp 648/udp # Registry Registrar Protocol (RRP) -rrp 648/tcp # Registry Registrar Protocol (RRP) -# Scott Hollenbeck -cadview-3d 649/udp # Cadview-3d - streaming 3d models over the internet -cadview-3d 649/tcp # Cadview-3d - streaming 3d models over the internet -# David Cooper -obex 650/udp # OBEX -obex 650/tcp # OBEX -# Jeff Garbers -ieee-mms 651/udp # IEEE MMS -ieee-mms 651/tcp # IEEE MMS -# Curtis Anderson -hello-port 652/udp # HELLO_PORT -hello-port 652/tcp # HELLO_PORT -# Patrick Cipiere -repscmd 653/udp # RepCmd -repscmd 653/tcp # RepCmd -# Scott Dale -aodv 654/udp # AODV -aodv 654/tcp # AODV -# Charles Perkins -tinc 655/udp # TINC -tinc 655/tcp # TINC -# Ivo Timmermans -spmp 656/udp # SPMP -spmp 656/tcp # SPMP -# Jakob Kaivo -rmc 657/udp # RMC -rmc 657/tcp # RMC -# Michael Schmidt -tenfold 658/udp # TenFold -tenfold 658/tcp # TenFold -# Louis Olszyk -# 659 Removed (2001-06-06) -mac-srvr-admin 660/udp # MacOS Server Admin -mac-srvr-admin 660/tcp # MacOS Server Admin -# Forest Hill -hap 661/udp # HAP -hap 661/tcp # HAP -# Igor Plotnikov -pftp 662/udp # PFTP -pftp 662/tcp # PFTP -# Ben Schluricke -purenoise 663/udp # PureNoise -purenoise 663/tcp # PureNoise -# Sam Osa -asf-secure-rmcp 664/udp # ASF Secure Remote Management and Control Protocol -asf-secure-rmcp 664/tcp # ASF Secure Remote Management and Control Protocol -# Carl First -sun-dr 665/udp # Sun DR -sun-dr 665/tcp # Sun DR -# Harinder Bhasin -mdqs 666/udp doom # -mdqs 666/tcp doom # -# -disclose 667/udp # campaign contribution disclosures - SDR Technologies -disclose 667/tcp # campaign contribution disclosures - SDR Technologies -# Jim Dixon -mecomm 668/udp # MeComm -mecomm 668/tcp # MeComm -meregister 669/udp # MeRegister -meregister 669/tcp # MeRegister -# Armin Sawusch -vacdsm-sws 670/udp # VACDSM-SWS -vacdsm-sws 670/tcp # VACDSM-SWS -vacdsm-app 671/udp # VACDSM-APP -vacdsm-app 671/tcp # VACDSM-APP -vpps-qua 672/udp # VPPS-QUA -vpps-qua 672/tcp # VPPS-QUA -cimplex 673/udp # CIMPLEX -cimplex 673/tcp # CIMPLEX -# Ulysses G. Smith Jr. -acap 674/udp # ACAP -acap 674/tcp # ACAP -# Chris Newman -dctp 675/udp # DCTP -dctp 675/tcp # DCTP -# Andre Kramer -vpps-via 676/udp # VPPS Via -vpps-via 676/tcp # VPPS Via -# Ulysses G. Smith Jr. -vpp 677/udp # Virtual Presence Protocol -vpp 677/tcp # Virtual Presence Protocol -# Klaus Wolf -ggf-ncp 678/udp # GNU Generation Foundation NCP -ggf-ncp 678/tcp # GNU Generation Foundation NCP -# Noah Paul -mrm 679/udp # MRM -mrm 679/tcp # MRM -# Liming Wei -entrust-aaas 680/udp # entrust-aaas -entrust-aaas 680/tcp # entrust-aaas -entrust-aams 681/udp # entrust-aams -entrust-aams 681/tcp # entrust-aams -# Adrian Mancini -xfr 682/udp # XFR -xfr 682/tcp # XFR -# Noah Paul -corba-iiop 683/udp # CORBA IIOP -corba-iiop 683/tcp # CORBA IIOP -corba-iiop-ssl 684/udp # CORBA IIOP SSL -corba-iiop-ssl 684/tcp # CORBA IIOP SSL -# Henry Lowe -mdc-portmapper 685/udp # MDC Port Mapper -mdc-portmapper 685/tcp # MDC Port Mapper -# Noah Paul -hcp-wismar 686/udp # Hardware Control Protocol Wismar -hcp-wismar 686/tcp # Hardware Control Protocol Wismar -# David Merchant -asipregistry 687/udp # asipregistry -asipregistry 687/tcp # asipregistry -# Erik Sea -realm-rusd 688/udp # REALM-RUSD -realm-rusd 688/tcp # REALM-RUSD -# Jerry Knight -nmap 689/udp # NMAP -nmap 689/tcp # NMAP -# Peter Dennis Bartok -vatp 690/udp # VATP -vatp 690/tcp # VATP -# Atica Software -msexch-routing 691/udp # MS Exchange Routing -msexch-routing 691/tcp # MS Exchange Routing -# David Lemson -hyperwave-isp 692/udp # Hyperwave-ISP -hyperwave-isp 692/tcp # Hyperwave-ISP -# Gerald Mesaric -connendp 693/udp # connendp -connendp 693/tcp # connendp -# Ronny Bremer -ha-cluster 694/udp # ha-cluster -ha-cluster 694/tcp # ha-cluster -# Alan Robertson -ieee-mms-ssl 695/udp # IEEE-MMS-SSL -ieee-mms-ssl 695/tcp # IEEE-MMS-SSL -# Curtis Anderson -rushd 696/udp # RUSHD -rushd 696/tcp # RUSHD -# Greg Ercolano -uuidgen 697/udp # UUIDGEN -uuidgen 697/tcp # UUIDGEN -# James Falkner -olsr 698/udp # OLSR -olsr 698/tcp # OLSR -# Thomas Clausen -accessnetwork 699/udp # Access Network -accessnetwork 699/tcp # Access Network -# Yingchun Xu -# 700-703 Unassigned -elcsd 704/udp # errlog copy/server daemon -elcsd 704/tcp # errlog copy/server daemon -agentx 705/udp # AgentX -agentx 705/tcp # AgentX -# Bob Natale -silc 706/udp # SILC -silc 706/tcp # SILC -# Pekka Riikonen -borland-dsj 707/udp # Borland DSJ -borland-dsj 707/tcp # Borland DSJ -# Gerg Cole -# 708 Unassigned -entrust-kmsh 709/udp # Entrust Key Management Service Handler -entrust-kmsh 709/tcp # Entrust Key Management Service Handler -entrust-ash 710/udp # Entrust Administration Service Handler -entrust-ash 710/tcp # Entrust Administration Service Handler -# Peter Whittaker -cisco-tdp 711/udp # Cisco TDP -cisco-tdp 711/tcp # Cisco TDP -# Bruce Davie -# 712-728 Unassigned -netviewdm1 729/udp # IBM NetView DM/6000 Server/Client -netviewdm1 729/tcp # IBM NetView DM/6000 Server/Client -netviewdm2 730/udp # IBM NetView DM/6000 send/tcp -netviewdm2 730/tcp # IBM NetView DM/6000 send/tcp -netviewdm3 731/udp # IBM NetView DM/6000 receive/tcp -netviewdm3 731/tcp # IBM NetView DM/6000 receive/tcp -# Philippe Binet (phbinet@vnet.IBM.COM) -# 732-740 Unassigned -netgw 741/udp # netGW -netgw 741/tcp # netGW -# Oliver Korfmacher (okorf@netcs.com) -netrcs 742/udp # Network based Rev. Cont. Sys. -netrcs 742/tcp # Network based Rev. Cont. Sys. -# Gordon C. Galligher -# 743 Unassigned -flexlm 744/udp # Flexible License Manager -flexlm 744/tcp # Flexible License Manager -# Matt Christiano -# -# 745-746 Unassigned -fujitsu-dev 747/udp # Fujitsu Device Control -fujitsu-dev 747/tcp # Fujitsu Device Control -ris-cm 748/udp # Russell Info Sci Calendar Manager -ris-cm 748/tcp # Russell Info Sci Calendar Manager -kerberos-adm 749/udp # kerberos administration -kerberos-adm 749/tcp # kerberos administration -loadav 750/udp kerberos-iv # -rfile 750/tcp # -# Martin Hamilton -pump 751/udp # -pump 751/tcp # -qrh 752/udp # -qrh 752/tcp # -rrh 753/udp # -rrh 753/tcp # -tell 754/udp # send -tell 754/tcp # send -# Josyula R. Rao -# 755-756 Unassigned -nlogin 758/udp # -nlogin 758/tcp # -con 759/udp # -con 759/tcp # -ns 760/udp # -ns 760/tcp # -rxe 761/udp # -rxe 761/tcp # -quotad 762/udp # -quotad 762/tcp # -cycleserv 763/udp # -cycleserv 763/tcp # -omserv 764/udp # -omserv 764/tcp # -webster 765/udp # -webster 765/tcp # -# Josyula R. Rao -# 766 Unassigned -phonebook 767/udp # phone -phonebook 767/tcp # phone -# Josyula R. Rao -# 768 Unassigned -vid 769/udp # -vid 769/tcp # -cadlock 770/udp # -cadlock 770/tcp # -rtip 771/udp # -rtip 771/tcp # -cycleserv2 772/udp # -cycleserv2 772/tcp # -notify 773/udp # -submit 773/tcp # -acmaint_dbd 774/udp # -rpasswd 774/tcp # -acmaint_transd 775/udp # -entomb 775/tcp # -wpages 776/udp # -wpages 776/tcp # -# Josyula R. Rao -multiling-http 777/udp # Multiling HTTP -multiling-http 777/tcp # Multiling HTTP -# Alejandro Bonet -# 778-779 Unassigned -wpgs 780/udp # -wpgs 780/tcp # -# Josyula R. Rao -# 781-785 Unassigned -# 786 Unassigned (Removed 2002-05-08) -# 787 Unassigned (Removed 2002-10-08) -# 788-799 Unassigned -mdbs_daemon 800/udp # -mdbs_daemon 800/tcp # -device 801/udp # -device 801/tcp # -# 802-809 Unassigned -fcp-udp 810/udp # FCP Datagram -fcp-udp 810/tcp # FCP -# Paul Whittemore -# 811-827 Unassigned -itm-mcell-s 828/udp # itm-mcell-s -itm-mcell-s 828/tcp # itm-mcell-s -# Miles O'Neal -pkix-3-ca-ra 829/udp # PKIX-3 CA/RA -pkix-3-ca-ra 829/tcp # PKIX-3 CA/RA -# Carlisle Adams -# 830-846 Unassigned -dhcp-failover2 847/udp # dhcp-failover 2 -dhcp-failover2 847/tcp # dhcp-failover 2 -# Bernard Volz -gdoi 848/udp # GDOI -gdoi 848/tcp # GDOI -# RFC-ietf-msec-gdoi-07.txt -# 849-859 Unassigned -iscsi 860/udp # iSCSI -iscsi 860/tcp # iSCSI -# RFC-draft-ietf-ips-iscsi-20.txt -# 861-872 Unassigned -rsync 873/udp # rsync -rsync 873/tcp # rsync -# Andrew Tridgell -# 874-885 Unassigned -iclcnet-locate 886/udp # ICL coNETion locate server -iclcnet-locate 886/tcp # ICL coNETion locate server -# Bob Lyon -iclcnet_svinfo 887/udp # ICL coNETion server info -iclcnet_svinfo 887/tcp # ICL coNETion server info -# Bob Lyon -accessbuilder 888/udp # AccessBuilder -accessbuilder 888/tcp # AccessBuilder -# Steve Sweeney -# The following entry records an unassigned but widespread use -cddbp 888/tcp # CD Database Protocol -# Steve Scherf -# -# 889-899 Unassigned -omginitialrefs 900/udp # OMG Initial Refs -omginitialrefs 900/tcp # OMG Initial Refs -# Christian Callsen -smpnameres 901/udp # SMPNAMERES -smpnameres 901/tcp # SMPNAMERES -# Leif Ekblad -ideafarm-chat 902/udp # IDEAFARM-CHAT -ideafarm-chat 902/tcp # IDEAFARM-CHAT -ideafarm-catch 903/udp # IDEAFARM-CATCH -ideafarm-catch 903/tcp # IDEAFARM-CATCH -# Wo'o Ideafarm -# 904-910 Unassigned -xact-backup 911/udp # xact-backup -xact-backup 911/tcp # xact-backup -# Bill Carroll -apex-mesh 912/udp # APEX relay-relay service -apex-mesh 912/tcp # APEX relay-relay service -apex-edge 913/udp # APEX endpoint-relay service -apex-edge 913/tcp # APEX endpoint-relay service -# [RFC3340] -# 914-988 Unassigned -ftps-data 989/udp # ftp protocol, data, over TLS/SSL -ftps-data 989/tcp # ftp protocol, data, over TLS/SSL -ftps 990/udp # ftp protocol, control, over TLS/SSL -ftps 990/tcp # ftp protocol, control, over TLS/SSL -# Christopher Allen -nas 991/udp # Netnews Administration System -nas 991/tcp # Netnews Administration System -# Vera Heinau -# Heiko Schlichting -telnets 992/udp # telnet protocol over TLS/SSL -telnets 992/tcp # telnet protocol over TLS/SSL -imaps 993/udp # imap4 protocol over TLS/SSL -imaps 993/tcp # imap4 protocol over TLS/SSL -ircs 994/udp # irc protocol over TLS/SSL -ircs 994/tcp # irc protocol over TLS/SSL -# Christopher Allen -pop3s 995/udp # pop3 protocol over TLS/SSL (was spop3) -pop3s 995/tcp # pop3 protocol over TLS/SSL (was spop3) -# Gordon Mangione -vsinet 996/udp # vsinet -vsinet 996/tcp # vsinet -# Rob Juergens -maitrd 997/udp # -maitrd 997/tcp # -puparp 998/udp # -busboy 998/tcp # -applix 999/udp puprouter # Applix ac -garcon 999/tcp puprouter # -cadlock2 1000/udp # -cadlock2 1000/tcp # -# 1001-1009 Unassigned -# 1008/udp Possibly used by Sun Solaris???? -surf 1010/udp # surf -surf 1010/tcp # surf -# Joseph Geer -# 1011-1022 Reserved - 1023/udp # Reserved - 1023/tcp # Reserved -# IANA - 1024/udp # Reserved - 1024/tcp # Reserved -# IANA -# -# REGISTERED PORT NUMBERS -# -blackjack 1025/udp # network blackjack -blackjack 1025/tcp # network blackjack -# Unknown contact -cap 1026/udp # Calender Access Protocol -cap 1026/tcp # Calender Access Protocol -# Doug Royer June 2002 -exosee 1027/udp # ExoSee -exosee 1027/tcp # ExoSee -# Chagdali Isamail June 2003 -# 1028-1029 Unassigned -iad1 1030/udp # BBN IAD -iad1 1030/tcp # BBN IAD -iad2 1031/udp # BBN IAD -iad2 1031/tcp # BBN IAD -iad3 1032/udp # BBN IAD -iad3 1032/tcp # BBN IAD -# Andy Malis -netinfo-local 1033/udp # local netinfo port -netinfo-local 1033/tcp # local netinfo port -# Marc Majka August 2002 -activesync 1034/udp # ActiveSync Notifications -activesync 1034/tcp # ActiveSync Notifications -# Sandra Vargas March 2003 -mxxrlogin 1035/udp # MX-XR RPC -mxxrlogin 1035/tcp # MX-XR RPC -# Arnold E. Mauer April 2003 -pcg-radar 1036/udp # RADAR Service Protocol -pcg-radar 1036/tcp # RADAR Service Protocol -# Steve Ravida -# 1037-1039 Unassigned -netarx 1040/udp # Netarx -netarx 1040/tcp # Netarx -# Fredrick Paul Eisele -# 1041-1044 Unassigned -fpitp 1045/udp # Fingerprint Image Transfer Protocol -fpitp 1045/tcp # Fingerprint Image Transfer Protocol -# Steven Fields February 2002 -# 1046 Unassigned -neod1 1047/udp # Sun's NEO Object Request Broker -neod1 1047/tcp # Sun's NEO Object Request Broker -neod2 1048/udp # Sun's NEO Object Request Broker -neod2 1048/tcp # Sun's NEO Object Request Broker -# Rohit Garg -td-postman 1049/udp # Tobit David Postman VPMN -td-postman 1049/tcp # Tobit David Postman VPMN -# Franz-Josef Leuders -cma 1050/udp # CORBA Management Agent -cma 1050/tcp # CORBA Management Agent -# Ramy Zaarour -optima-vnet 1051/udp # Optima VNET -optima-vnet 1051/tcp # Optima VNET -# Ralf Doewich -ddt 1052/udp # Dynamic DNS Tools -ddt 1052/tcp # Dynamic DNS Tools -# Remi Lefebvre -remote-as 1053/udp # Remote Assistant (RA) -remote-as 1053/tcp # Remote Assistant (RA) -# Roman Kriis -brvread 1054/udp # BRVREAD -brvread 1054/tcp # BRVREAD -# Gilles Roussel -ansyslmd 1055/udp # ANSYS - License Manager -ansyslmd 1055/tcp # ANSYS - License Manager -# Suzanne Lorrin -vfo 1056/udp # VFO -vfo 1056/tcp # VFO -# Anthony Gonzalez -startron 1057/udp # STARTRON -startron 1057/tcp # STARTRON -# Markus Sabadello -nim 1058/udp # nim -nim 1058/tcp # nim -nimreg 1059/udp # nimreg -nimreg 1059/tcp # nimreg -# Robert Gordon -polestar 1060/udp # POLESTAR -polestar 1060/tcp # POLESTAR -# Masakuni Okada -kiosk 1061/udp # KIOSK -kiosk 1061/tcp # KIOSK -# Howard Buck -veracity 1062/udp # Veracity -veracity 1062/tcp # Veracity -# Ross Williams -kyoceranetdev 1063/udp # KyoceraNetDev -kyoceranetdev 1063/tcp # KyoceraNetDev -# Shigenaka Kanemitsu -# -jstel 1064/udp # JSTEL -jstel 1064/tcp # JSTEL -# Duane Kiser -syscomlan 1065/udp # SYSCOMLAN -syscomlan 1065/tcp # SYSCOMLAN -# Urs Ryf -fpo-fns 1066/udp # FPO-FNS -fpo-fns 1066/tcp # FPO-FNS -# Jens Klose -instl_boots 1067/udp # Installation Bootstrap Proto. Serv. -instl_boots 1067/tcp # Installation Bootstrap Proto. Serv. -instl_bootc 1068/udp # Installation Bootstrap Proto. Cli. -instl_bootc 1068/tcp # Installation Bootstrap Proto. Cli. -# David Arko -cognex-insight 1069/udp # COGNEX-INSIGHT -cognex-insight 1069/tcp # COGNEX-INSIGHT -# Steve Olson -gmrupdateserv 1070/udp # GMRUpdateSERV -gmrupdateserv 1070/tcp # GMRUpdateSERV -# Steve Kellogg -bsquare-voip 1071/udp # BSQUARE-VOIP -bsquare-voip 1071/tcp # BSQUARE-VOIP -# Yen Lee -cardax 1072/udp # CARDAX -cardax 1072/tcp # CARDAX -# Charles Oram -bridgecontrol 1073/udp # Bridge Control -bridgecontrol 1073/tcp # Bridge Control -# Andy Heron -fastechnologlm 1074/udp # FASTechnologies License Manager -fastechnologlm 1074/tcp # FASTechnologies License Manager -# Robert C. Henningsgard -# -rdrmshc 1075/udp # RDRMSHC -rdrmshc 1075/tcp # RDRMSHC -# Ericko Shimada -dab-sti-c 1076/udp # DAB STI-C -dab-sti-c 1076/tcp # DAB STI-C -# World DAB -imgames 1077/udp # IMGames -imgames 1077/tcp # IMGames -# Jean A. Ames -avocent-proxy 1078/udp # Avocent Proxy Protocol -avocent-proxy 1078/tcp # Avocent Proxy Protocol -# Steven W. Clark -asprovatalk 1079/udp # ASPROVATalk -asprovatalk 1079/tcp # ASPROVATalk -# Chiew Farn Chung -socks 1080/udp # Socks -socks 1080/tcp # Socks -# Ying-Da Lee Peter.Lipp@iaik.at> -amt-esd-prot 1082/udp # AMT-ESD-PROT -amt-esd-prot 1082/tcp # AMT-ESD-PROT -# AMTEC S.p.A -ansoft-lm-1 1083/udp # Anasoft License Manager -ansoft-lm-1 1083/tcp # Anasoft License Manager -ansoft-lm-2 1084/udp # Anasoft License Manager -ansoft-lm-2 1084/tcp # Anasoft License Manager -webobjects 1085/udp # Web Objects -webobjects 1085/tcp # Web Objects -# Andy Belk -cplscrambler-lg 1086/udp # CPL Scrambler Logging -cplscrambler-lg 1086/tcp # CPL Scrambler Logging -cplscrambler-in 1087/udp # CPL Scrambler Internal -cplscrambler-in 1087/tcp # CPL Scrambler Internal -cplscrambler-al 1088/udp # CPL Scrambler Alarm Log -cplscrambler-al 1088/tcp # CPL Scrambler Alarm Log -# Richard Corn -ff-annunc 1089/udp # FF Annunciation -ff-annunc 1089/tcp # FF Annunciation -ff-fms 1090/udp # FF Fieldbus Message Specification -ff-fms 1090/tcp # FF Fieldbus Message Specification -ff-sm 1091/udp # FF System Management -ff-sm 1091/tcp # FF System Management -# Fieldbus Foundation -obrpd 1092/udp # Open Business Reporting Protocol -obrpd 1092/tcp # Open Business Reporting Protocol -# William Randolph Royere III -# -proofd 1093/udp # PROOFD -proofd 1093/tcp # PROOFD -rootd 1094/udp # ROOTD -rootd 1094/tcp # ROOTD -# Fons Rademakers -nicelink 1095/udp # NICELink -nicelink 1095/tcp # NICELink -# Jordi Lisbona -cnrprotocol 1096/udp # Common Name Resolution Protocol -cnrprotocol 1096/tcp # Common Name Resolution Protocol -# Michael Mealling -sunclustermgr 1097/udp # Sun Cluster Manager -sunclustermgr 1097/tcp # Sun Cluster Manager -# Ashit Patel -rmiactivation 1098/udp # RMI Activation -rmiactivation 1098/tcp # RMI Activation -rmiregistry 1099/udp # RMI Registry -rmiregistry 1099/tcp # RMI Registry -# Mark Hodapp -mctp 1100/udp # MCTP -mctp 1100/tcp # MCTP -# Vitaly Revsin -pt2-discover 1101/udp # PT2-DISCOVER -pt2-discover 1101/tcp # PT2-DISCOVER -# Ralph Kammerlander -# -adobeserver-1 1102/udp # ADOBE SERVER 1 -adobeserver-1 1102/tcp # ADOBE SERVER 1 -adobeserver-2 1103/udp # ADOBE SERVER 2 -adobeserver-2 1103/tcp # ADOBE SERVER 2 -# Frank Soetebeer -xrl 1104/udp # XRL -xrl 1104/tcp # XRL -# Patrick Robinson -ftranhc 1105/udp # FTRANHC -ftranhc 1105/tcp # FTRANHC -# Eriko Shimada -isoipsigport-1 1106/udp # ISOIPSIGPORT-1 -isoipsigport-1 1106/tcp # ISOIPSIGPORT-1 -isoipsigport-2 1107/udp # ISOIPSIGPORT-2 -isoipsigport-2 1107/tcp # ISOIPSIGPORT-2 -# Peter Egli -ratio-adp 1108/udp # ratio-adp -ratio-adp 1108/tcp # ratio-adp -# Oliver Thulke -# 1109 Reserved - IANA -nfsd-keepalive 1110/udp # Client status info -nfsd-status 1110/tcp # Cluster status info -# Edgar Circenis -lmsocialserver 1111/udp # LM Social Server -lmsocialserver 1111/tcp # LM Social Server -# Ron Lussier -icp 1112/udp # Intelligent Communication Protocol -icp 1112/tcp # Intelligent Communication Protocol -# Mark H. David -# 1113 Unassigned -mini-sql 1114/udp # Mini SQL -mini-sql 1114/tcp # Mini SQL -# David Hughes -ardus-trns 1115/udp # ARDUS Transfer -ardus-trns 1115/tcp # ARDUS Transfer -ardus-cntl 1116/udp # ARDUS Control -ardus-cntl 1116/tcp # ARDUS Control -ardus-mtrns 1117/udp # ARDUS Multicast Transfer -ardus-mtrns 1117/tcp # ARDUS Multicast Transfer -# Shinya Abe -# 1118-1121 Unassigned -availant-mgr 1122/udp # availant-mgr -availant-mgr 1122/tcp # availant-mgr -# Steven Pelletier -murray 1123/udp # Murray -murray 1123/tcp # Murray -# Stu Mark -# 1124-1154 Unassigned -nfa 1155/udp # Network File Access -nfa 1155/tcp # Network File Access -# James Powell -# 1156-1160 Unassigned -health-polling 1161/udp # Health Polling -health-polling 1161/tcp # Health Polling -health-trap 1162/udp # Health Trap -health-trap 1162/tcp # Health Trap -# 1163-1167 Unassigned -vchat 1168/udp # VChat Conference Service -vchat 1168/tcp # VChat Conference Service -# Andreas Wetzel September 2002 -tripwire 1169/udp # TRIPWIRE -tripwire 1169/tcp # TRIPWIRE -# Ed Metcalf -# Albert Holt -# 1170-1179 Unassigned -mc-client 1180/udp # Millicent Client Proxy -mc-client 1180/tcp # Millicent Client Proxy -# Steve Glassman -# 1181-1182 Unassigned -llsurfup-http 1183/udp # LL Surfup HTTP -llsurfup-http 1183/tcp # LL Surfup HTTP -llsurfup-https 1184/udp # LL Surfup HTTPS -llsurfup-https 1184/tcp # LL Surfup HTTPS -# Katy Lynn McCullough -catchpole 1185/udp # Catchpole port -catchpole 1185/tcp # Catchpole port -# Christian Catchpole March 2002 -# 1186-1187 Unassigned -hp-webadmin 1188/udp # HP Web Admin -hp-webadmin 1188/tcp # HP Web Admin -# Lance Kind -# 1189-1198 Unassigned -dmidi 1199/udp # DMIDI -dmidi 1199/tcp # DMIDI -# Phil Kerr February 2002 -scol 1200/udp # SCOL -scol 1200/tcp # SCOL -# Cryo-Networks -nucleus-sand 1201/udp # Nucleus Sand -nucleus-sand 1201/tcp # Nucleus Sand -# James Marsh -caiccipc 1202/udp # caiccipc -caiccipc 1202/tcp # caiccipc -# Vince Re -ssslic-mgr 1203/udp # License Validation -ssslic-mgr 1203/tcp # License Validation -ssslog-mgr 1204/udp # Log Request Listener -ssslog-mgr 1204/tcp # Log Request Listener -# Eric Bruno -accord-mgc 1205/udp # Accord-MGC -accord-mgc 1205/tcp # Accord-MGC -# Roni Even -anthony-data 1206/udp # Anthony Data -anthony-data 1206/tcp # Anthony Data -# Paul Dollemore -metasage 1207/udp # MetaSage -metasage 1207/tcp # MetaSage -# Peter Anvelt -seagull-ais 1208/udp # SEAGULL AIS -seagull-ais 1208/tcp # SEAGULL AIS -# Lee Breisacher -ipcd3 1209/udp # IPCD3 -ipcd3 1209/tcp # IPCD3 -# Mark Ciskey -eoss 1210/udp # EOSS -eoss 1210/tcp # EOSS -# Robert Armes -groove-dpp 1211/udp # Groove DPP -groove-dpp 1211/tcp # Groove DPP -# Ken Moore -lupa 1212/udp # lupa -lupa 1212/tcp # lupa -# Barney Wolff -mpc-lifenet 1213/udp # MPC LIFENET -mpc-lifenet 1213/tcp # MPC LIFENET -# Ward Silver -kazaa 1214/udp # KAZAA -kazaa 1214/tcp # KAZAA -# Ahti Heinla -scanstat-1 1215/udp # scanSTAT 1.0 -scanstat-1 1215/tcp # scanSTAT 1.0 -# William Scheding -etebac5 1216/udp # ETEBAC 5 -etebac5 1216/tcp # ETEBAC 5 -# GSIT -hpss-ndapi 1217/udp # HPSS-NDAPI -hpss-ndapi 1217/tcp # HPSS-NDAPI -# Michael Gleicher -aeroflight-ads 1218/udp # AeroFlight-ADs -aeroflight-ads 1218/tcp # AeroFlight-ADs -aeroflight-ret 1219/udp # AeroFlight-Ret -aeroflight-ret 1219/tcp # AeroFlight-Ret -# Eric Johnson -qt-serveradmin 1220/udp # QT SERVER ADMIN -qt-serveradmin 1220/tcp # QT SERVER ADMIN -# Chris LeCroy -sweetware-apps 1221/udp # SweetWARE Apps -sweetware-apps 1221/tcp # SweetWARE Apps -# David Dunetz -nerv 1222/udp # SNI R&D network -nerv 1222/tcp # SNI R&D network -# Martin Freiss -tgp 1223/udp # TGP -tgp 1223/tcp # TGP -# Gur Kimchi -vpnz 1224/udp # VPNz -vpnz 1224/tcp # VPNz -# Tom Strack -slinkysearch 1225/udp # SLINKYSEARCH -slinkysearch 1225/tcp # SLINKYSEARCH -# Desmond Chan -stgxfws 1226/udp # STGXFWS -stgxfws 1226/tcp # STGXFWS -# Tetsuya Shioda -dns2go 1227/udp # DNS2Go -dns2go 1227/tcp # DNS2Go -# Mark Richards -florence 1228/udp # FLORENCE -florence 1228/tcp # FLORENCE -# Brian Trammell -novell-zfs 1229/udp # Novell ZFS -novell-zfs 1229/tcp # Novell ZFS -# Ty Ellis -periscope 1230/udp # Periscope -periscope 1230/tcp # Periscope -# Kevin Madden -menandmice-lpm 1231/udp # menandmice-lpm -menandmice-lpm 1231/tcp # menandmice-lpm -# Sigfus Magnusson -##### Microsoft (unoffically) using 1232 ##### -univ-appserver 1233/udp # Universal App Server -univ-appserver 1233/tcp # Universal App Server -# Tim Sent -search-agent 1234/udp # Infoseek Search Agent -search-agent 1234/tcp # Infoseek Search Agent -# Jackie Wu -mosaicsyssvc1 1235/udp # mosaicsyssvc1 -mosaicsyssvc1 1235/tcp # mosaicsyssvc1 -# Brian Matthews -bvcontrol 1236/udp # bvcontrol -bvcontrol 1236/tcp # bvcontrol -# Daniel J Walsh -tsdos390 1237/udp # tsdos390 -tsdos390 1237/tcp # tsdos390 -# Ben Pracht -hacl-qs 1238/udp # hacl-qs -hacl-qs 1238/tcp # hacl-qs -# Farid Faez -nmsd 1239/udp # NMSD -nmsd 1239/tcp # NMSD -# Yuri Machkasov -instantia 1240/udp # Instantia -instantia 1240/tcp # Instantia -# Ruth Slater -nessus 1241/udp # nessus -nessus 1241/tcp # nessus -# Jordan Hrycaj -nmasoverip 1242/udp # NMAS over IP -nmasoverip 1242/tcp # NMAS over IP -# Hal Henderson -serialgateway 1243/udp # SerialGateway -serialgateway 1243/tcp # SerialGateway -# Stephen LaValley -isbconference1 1244/udp # isbconference1 -isbconference1 1244/tcp # isbconference1 -isbconference2 1245/udp # isbconference2 -isbconference2 1245/tcp # isbconference2 -# Arnold Dittmann -payrouter 1246/udp # payrouter -payrouter 1246/tcp # payrouter -# David Wilson -visionpyramid 1247/udp # VisionPyramid -visionpyramid 1247/tcp # VisionPyramid -# Gavin Hutchinson -hermes 1248/udp # hermes -hermes 1248/tcp # hermes -# Not known -mesavistaco 1249/udp # Mesa Vista Co -mesavistaco 1249/tcp # Mesa Vista Co -# Rick LaBanca -swldy-sias 1250/udp # swldy-sias -swldy-sias 1250/tcp # swldy-sias -# Peter E Williams -servergraph 1251/udp # servergraph -servergraph 1251/tcp # servergraph -# Lindsay Morris -bspne-pcc 1252/udp # bspne-pcc -bspne-pcc 1252/tcp # bspne-pcc -q55-pcc 1253/udp # q55-pcc -q55-pcc 1253/tcp # q55-pcc -# Prem Tirilok -de-noc 1254/udp # de-noc -de-noc 1254/tcp # de-noc -de-cache-query 1255/udp # de-cache-query -de-cache-query 1255/tcp # de-cache-query -de-server 1256/udp # de-server -de-server 1256/tcp # de-server -# Jeff Burdette -shockwave2 1257/udp # Shockwave 2 -shockwave2 1257/tcp # Shockwave 2 -# Dave Simmons -opennl 1258/udp # Open Network Library -opennl 1258/tcp # Open Network Library -opennl-voice 1259/udp # Open Network Library Voice -opennl-voice 1259/tcp # Open Network Library Voice -# Phil Frisbie -ibm-ssd 1260/udp # ibm-ssd -ibm-ssd 1260/tcp # ibm-ssd -# Barry Whyte -mpshrsv 1261/udp # mpshrsv -mpshrsv 1261/tcp # mpshrsv -# Makoto Ikeyama -qnts-orb 1262/udp # QNTS-ORB -qnts-orb 1262/tcp # QNTS-ORB -# Raghurama Bhat -dka 1263/udp # dka -dka 1263/tcp # dka -# Chris Griffin -prat 1264/udp # PRAT -prat 1264/tcp # PRAT -# Keith Wood -dssiapi 1265/udp # DSSIAPI -dssiapi 1265/tcp # DSSIAPI -# Steve Sando -dellpwrappks 1266/udp # DELLPWRAPPKS -dellpwrappks 1266/tcp # DELLPWRAPPKS -# David Troeger -epc 1267/udp # eTrust Policy Compliance -epc 1267/tcp # eTrust Policy Compliance -# Aaron Stein -propel-msgsys 1268/udp # PROPEL-MSGSYS -propel-msgsys 1268/tcp # PROPEL-MSGSYS -# Bert Van der Linden -watilapp 1269/udp # WATiLaPP -watilapp 1269/tcp # WATiLaPP -# Frederic Weymann -opsmgr 1270/udp # Microsoft Operations Manager -opsmgr 1270/tcp # Microsoft Operations Manager -# Ashvin Sanghvi -dabew 1271/udp # Dabew -dabew 1271/tcp # Dabew -# Norm Freedman -cspmlockmgr 1272/udp # CSPMLockMgr -cspmlockmgr 1272/tcp # CSPMLockMgr -# Ibtsam Mahfouz -emc-gateway 1273/udp # EMC-Gateway -emc-gateway 1273/tcp # EMC-Gateway -# Rene Fontaine -t1distproc 1274/udp # t1distproc -t1distproc 1274/tcp # t1distproc -# Julian Biddle -ivcollector 1275/udp # ivcollector -ivcollector 1275/tcp # ivcollector -ivmanager 1276/udp # ivmanager -ivmanager 1276/tcp # ivmanager -# Xavier Roques -miva-mqs 1277/udp # mqs -miva-mqs 1277/tcp # mqs -# Miva Corporation -dellwebadmin-1 1278/udp # Dell Web Admin 1 -dellwebadmin-1 1278/tcp # Dell Web Admin 1 -dellwebadmin-2 1279/udp # Dell Web Admin 2 -dellwebadmin-2 1279/tcp # Dell Web Admin 2 -# Bridget Navoda -pictrography 1280/udp # Pictrography -pictrography 1280/tcp # Pictrography -# Takashi Hoshino -healthd 1281/udp # healthd -healthd 1281/tcp # healthd -# James E. Housley -emperion 1282/udp # Emperion -emperion 1282/tcp # Emperion -# Claus Thor Barth -productinfo 1283/udp # ProductInfo -productinfo 1283/tcp # ProductInfo -iee-qfx 1284/udp # IEE-QFX -iee-qfx 1284/tcp # IEE-QFX -# Kevin D. Quitt -neoiface 1285/udp # neoiface -neoiface 1285/tcp # neoiface -# Jason McManus -netuitive 1286/udp # netuitive -netuitive 1286/tcp # netuitive -# Clayton Wilkinson -# 1287 Unassigned -navbuddy 1288/udp # NavBuddy -navbuddy 1288/tcp # NavBuddy -# Eric Hackman -jwalkserver 1289/udp # JWalkServer -jwalkserver 1289/tcp # JWalkServer -winjaserver 1290/udp # WinJaServer -winjaserver 1290/tcp # WinJaServer -seagulllms 1291/udp # SEAGULLLMS -seagulllms 1291/tcp # SEAGULLLMS -# Lee Breisacher -dsdn 1292/udp # dsdn -dsdn 1292/tcp # dsdn -# Stanislaw Skowronek -pkt-krb-ipsec 1293/udp # PKT-KRB-IPSec -pkt-krb-ipsec 1293/tcp # PKT-KRB-IPSec -# Nancy Davoust -cmmdriver 1294/udp # CMMdriver -cmmdriver 1294/tcp # CMMdriver -# Lutz Karras -ehtp 1295/udp # End-by-Hop Transmission Protocol -ehtp 1295/tcp # End-by-Hop Transmission Protocol -# Alexander Bogdanov -dproxy 1296/udp # dproxy -dproxy 1296/tcp # dproxy -sdproxy 1297/udp # sdproxy -sdproxy 1297/tcp # sdproxy -# Raimond Diederik -lpcp 1298/udp # lpcp -lpcp 1298/tcp # lpcp -# Christian Stredicke -hp-sci 1299/udp # hp-sci -hp-sci 1299/tcp # hp-sci -# Kim Scott -h323hostcallsc 1300/udp # H323 Host Call Secure -h323hostcallsc 1300/tcp # H323 Host Call Secure -# Jim Toga -ci3-software-1 1301/udp # CI3-Software-1 -ci3-software-1 1301/tcp # CI3-Software-1 -ci3-software-2 1302/udp # CI3-Software-2 -ci3-software-2 1302/tcp # CI3-Software-2 -# Kelli Watson -sftsrv 1303/udp # sftsrv -sftsrv 1303/tcp # sftsrv -# Robert Frazier -boomerang 1304/udp # Boomerang -boomerang 1304/tcp # Boomerang -# Bruce Lueckenhoff -pe-mike 1305/udp # pe-mike -pe-mike 1305/tcp # pe-mike -# Stephen Hemminger -re-conn-proto 1306/udp # RE-Conn-Proto -re-conn-proto 1306/tcp # RE-Conn-Proto -# Sandeep Singhal -pacmand 1307/udp # Pacmand -pacmand 1307/tcp # Pacmand -# Edward T. O'Shea -odsi 1308/udp # Optical Domain Service Interconnect (ODSI) -odsi 1308/tcp # Optical Domain Service Interconnect (ODSI) -# K. Arvind -jtag-server 1309/udp # JTAG server -jtag-server 1309/tcp # JTAG server -# Andrew Draper -husky 1310/udp # Husky -husky 1310/tcp # Husky -# Mark Zang -rxmon 1311/udp # RxMon -rxmon 1311/tcp # RxMon -# Javier Jiminez -sti-envision 1312/udp # STI Envision -sti-envision 1312/tcp # STI Envision -# Don Stedman -bmc_patroldb 1313/udp # BMC_PATROLDB -bmc_patroldb 1313/tcp # BMC_PATROLDB -# Devon Shows -pdps 1314/udp # Photoscript Distributed Printing System -pdps 1314/tcp # Photoscript Distributed Printing System -# Les Klein -els 1315/udp # E.L.S., Event Listener Service -els 1315/tcp # E.L.S., Event Listener Service -# Jim Cleppe -exbit-escp 1316/udp # Exbit-ESCP -exbit-escp 1316/tcp # Exbit-ESCP -# Morten Christensen -vrts-ipcserver 1317/udp # vrts-ipcserver -vrts-ipcserver 1317/tcp # vrts-ipcserver -# Bruce Hestand -krb5gatekeeper 1318/udp # krb5gatekeeper -krb5gatekeeper 1318/tcp # krb5gatekeeper -# Patrick Moore -panja-icsp 1319/udp # Panja-ICSP -panja-icsp 1319/tcp # Panja-ICSP -# Ron Barber -panja-axbnet 1320/udp # Panja-AXBNET -panja-axbnet 1320/tcp # Panja-AXBNET -# Andrew van Wensen -pip 1321/udp # PIP -pip 1321/tcp # PIP -# Gordon Mohr -novation 1322/udp # Novation -novation 1322/tcp # Novation -# Alan Dano -brcd 1323/udp # brcd -brcd 1323/tcp # brcd -# Todd Picquelle -delta-mcp 1324/udp # delta-mcp -delta-mcp 1324/tcp # delta-mcp -# Quinton Tormanen -dx-instrument 1325/udp # DX-Instrument -dx-instrument 1325/tcp # DX-Instrument -# Walt Modic -wimsic 1326/udp # WIMSIC -wimsic 1326/tcp # WIMSIC -# James Brown -ultrex 1327/udp # Ultrex -ultrex 1327/tcp # Ultrex -# Tim Walsh -ewall 1328/udp # EWALL -ewall 1328/tcp # EWALL -# Jeff Busma -netdb-export 1329/udp # netdb-export -netdb-export 1329/tcp # netdb-export -# Konstantinos Kostis -streetperfect 1330/udp # StreetPerfect -streetperfect 1330/tcp # StreetPerfect -# Michael R. Young -intersan 1331/udp # intersan -intersan 1331/tcp # intersan -# Barry H. Feild -pcia-rxp-b 1332/udp # PCIA RXP-B -pcia-rxp-b 1332/tcp # PCIA RXP-B -# James Dabbs -passwrd-policy 1333/udp # Password Policy -passwrd-policy 1333/tcp # Password Policy -# Tonio Pirotta -writesrv 1334/udp # writesrv -writesrv 1334/tcp # writesrv -# Marvin Toungate -digital-notary 1335/udp # Digital Notary Protocol -digital-notary 1335/tcp # Digital Notary Protocol -# Wes Doonan -ischat 1336/udp # Instant Service Chat -ischat 1336/tcp # Instant Service Chat -# Mike Clise -menandmice-dns 1337/udp # menandmice DNS -menandmice-dns 1337/tcp # menandmice DNS -# Sigfus Magnusson -wmc-log-svc 1338/udp # WMC-log-svr -wmc-log-svc 1338/tcp # WMC-log-svr -# Stephen Brosseau -kjtsiteserver 1339/udp # kjtsiteserver -kjtsiteserver 1339/tcp # kjtsiteserver -# Jason Aubain -naap 1340/udp # NAAP -naap 1340/tcp # NAAP -# Henry Haverinen -qubes 1341/udp # QuBES -qubes 1341/tcp # QuBES -# Eric Grange -esbroker 1342/udp # ESBroker -esbroker 1342/tcp # ESBroker -# Alexander Medvinsky -re101 1343/udp # re101 -re101 1343/tcp # re101 -# Doriano Blengino -icap 1344/udp # ICAP -icap 1344/tcp # ICAP -# Jeremy Elson -vpjp 1345/udp # VPJP -vpjp 1345/tcp # VPJP -# Michael Collins -alta-ana-lm 1346/udp # Alta Analytics License Manager -alta-ana-lm 1346/tcp # Alta Analytics License Manager -bbn-mmc 1347/udp # multi media conferencing -bbn-mmc 1347/tcp # multi media conferencing -bbn-mmx 1348/udp # multi media conferencing -bbn-mmx 1348/tcp # multi media conferencing -sbook 1349/udp # Registration Network Protocol -sbook 1349/tcp # Registration Network Protocol -editbench 1350/udp # Registration Network Protocol -editbench 1350/tcp # Registration Network Protocol -# Simson L. Garfinkel -equationbuilder 1351/udp # Digital Tool Works (MIT) -equationbuilder 1351/tcp # Digital Tool Works (MIT) -# Terrence J. Talbot -lotusnote 1352/udp # Lotus Note -lotusnote 1352/tcp # Lotus Note -# Greg Pflaum -relief 1353/udp # Relief Consulting -relief 1353/tcp # Relief Consulting -# John Feiler -rightbrain 1354/udp # RightBrain Software -rightbrain 1354/tcp # RightBrain Software -# Glenn Reid -intuitive-edge 1355/udp # Intuitive Edge -intuitive-edge 1355/tcp # Intuitive Edge -# Montgomery Zukowski -# -cuillamartin 1356/udp # CuillaMartin Company -cuillamartin 1356/tcp # CuillaMartin Company -pegboard 1357/udp # Electronic PegBoard -pegboard 1357/tcp # Electronic PegBoard -# Chris Cuilla -# -connlcli 1358/udp # CONNLCLI -connlcli 1358/tcp # CONNLCLI -ftsrv 1359/udp # FTSRV -ftsrv 1359/tcp # FTSRV -# Ines Homem de Melo -mimer 1360/udp # MIMER -mimer 1360/tcp # MIMER -# Per Schroeder -linx 1361/udp # LinX -linx 1361/tcp # LinX -# Steffen Schilke <---none---> -timeflies 1362/udp # TimeFlies -timeflies 1362/tcp # TimeFlies -# Doug Kent -ndm-requester 1363/udp # Network DataMover Requester -ndm-requester 1363/tcp # Network DataMover Requester -ndm-server 1364/udp # Network DataMover Server -ndm-server 1364/tcp # Network DataMover Server -# Toshio Watanabe -# -adapt-sna 1365/udp # Network Software Associates -adapt-sna 1365/tcp # Network Software Associates -# Jeffery Chiao <714-768-401> -netware-csp 1366/udp # Novell NetWare Comm Service Platform -netware-csp 1366/tcp # Novell NetWare Comm Service Platform -# Laurie Lindsey -dcs 1367/udp # DCS -dcs 1367/tcp # DCS -# Stefan Siebert -screencast 1368/udp # ScreenCast -screencast 1368/tcp # ScreenCast -# Bill Tschumy -gv-us 1369/udp # GlobalView to Unix Shell -gv-us 1369/tcp # GlobalView to Unix Shell -us-gv 1370/udp # Unix Shell to GlobalView -us-gv 1370/tcp # Unix Shell to GlobalView -# Makoto Mita -fc-cli 1371/udp # Fujitsu Config Protocol -fc-cli 1371/tcp # Fujitsu Config Protocol -fc-ser 1372/udp # Fujitsu Config Protocol -fc-ser 1372/tcp # Fujitsu Config Protocol -# Ryuichi Horie -chromagrafx 1373/udp # Chromagrafx -chromagrafx 1373/tcp # Chromagrafx -# Mike Barthelemy -molly 1374/udp # EPI Software Systems -molly 1374/tcp # EPI Software Systems -# Jim Vlcek -bytex 1375/udp # Bytex -bytex 1375/tcp # Bytex -# Mary Ann Burt -ibm-pps 1376/udp # IBM Person to Person Software -ibm-pps 1376/tcp # IBM Person to Person Software -# Simon Phipps -cichlid 1377/udp # Cichlid License Manager -cichlid 1377/tcp # Cichlid License Manager -# Andy Burgess -elan 1378/udp # Elan License Manager -elan 1378/tcp # Elan License Manager -# Ken Greer -dbreporter 1379/udp # Integrity Solutions -dbreporter 1379/tcp # Integrity Solutions -# Tim Dawson -telesis-licman 1380/udp # Telesis Network License Manager -telesis-licman 1380/tcp # Telesis Network License Manager -# Karl Schendel, Jr. -apple-licman 1381/udp # Apple Network License Manager -apple-licman 1381/tcp # Apple Network License Manager -# Earl Wallace -udt_os 1382/udp # udt_os -udt_os 1382/tcp # udt_os -gwha 1383/udp # GW Hannaway Network License Manager -gwha 1383/tcp # GW Hannaway Network License Manager -# J. Gabriel Foster -os-licman 1384/udp # Objective Solutions License Manager -os-licman 1384/tcp # Objective Solutions License Manager -# Donald Cornwell -atex_elmd 1385/udp # Atex Publishing License Manager -atex_elmd 1385/tcp # Atex Publishing License Manager -# Brett Sorenson -checksum 1386/udp # CheckSum License Manager -checksum 1386/tcp # CheckSum License Manager -# Andreas Glocker -cadsi-lm 1387/udp # Computer Aided Design Software Inc LM -cadsi-lm 1387/tcp # Computer Aided Design Software Inc LM -# Sulistio Muljadi -objective-dbc 1388/udp # Objective Solutions DataBase Cache -objective-dbc 1388/tcp # Objective Solutions DataBase Cache -# Donald Cornwell -iclpv-dm 1389/udp # Document Manager -iclpv-dm 1389/tcp # Document Manager -iclpv-sc 1390/udp # Storage Controller -iclpv-sc 1390/tcp # Storage Controller -iclpv-sas 1391/udp # Storage Access Server -iclpv-sas 1391/tcp # Storage Access Server -iclpv-pm 1392/udp # Print Manager -iclpv-pm 1392/tcp # Print Manager -iclpv-nls 1393/udp # Network Log Server -iclpv-nls 1393/tcp # Network Log Server -iclpv-nlc 1394/udp # Network Log Client -iclpv-nlc 1394/tcp # Network Log Client -iclpv-wsm 1395/udp # PC Workstation Manager software -iclpv-wsm 1395/tcp # PC Workstation Manager software -# A.P. Hobson -dvl-activemail 1396/udp # DVL Active Mail -dvl-activemail 1396/tcp # DVL Active Mail -audio-activmail 1397/udp # Audio Active Mail -audio-activmail 1397/tcp # Audio Active Mail -video-activmail 1398/udp # Video Active Mail -video-activmail 1398/tcp # Video Active Mail -# Avshalom Houri -cadkey-licman 1399/udp # Cadkey License Manager -cadkey-licman 1399/tcp # Cadkey License Manager -cadkey-tablet 1400/udp # Cadkey Tablet Daemon -cadkey-tablet 1400/tcp # Cadkey Tablet Daemon -# Joe McCollough -goldleaf-licman 1401/udp # Goldleaf License Manager -goldleaf-licman 1401/tcp # Goldleaf License Manager -# John Fox <---none---> -prm-sm-np 1402/udp # Prospero Resource Manager -prm-sm-np 1402/tcp # Prospero Resource Manager -prm-nm-np 1403/udp # Prospero Resource Manager -prm-nm-np 1403/tcp # Prospero Resource Manager -# B. Clifford Neuman -igi-lm 1404/udp # Infinite Graphics License Manager -igi-lm 1404/tcp # Infinite Graphics License Manager -ibm-res 1405/udp # IBM Remote Execution Starter -ibm-res 1405/tcp # IBM Remote Execution Starter -netlabs-lm 1406/udp # NetLabs License Manager -netlabs-lm 1406/tcp # NetLabs License Manager -dbsa-lm 1407/udp # DBSA License Manager -dbsa-lm 1407/tcp # DBSA License Manager -# Scott Shattuck -sophia-lm 1408/udp # Sophia License Manager -sophia-lm 1408/tcp # Sophia License Manager -# Eric Brown -here-lm 1409/udp # Here License Manager -here-lm 1409/tcp # Here License Manager -# David Ison -hiq 1410/udp # HiQ License Manager -hiq 1410/tcp # HiQ License Manager -# Rick Pugh -af 1411/udp # AudioFile -af 1411/tcp # AudioFile -# Jim Gettys -innosys 1412/udp # InnoSys -innosys 1412/tcp # InnoSys -innosys-acl 1413/udp # Innosys-ACL -innosys-acl 1413/tcp # Innosys-ACL -# Eric Welch <--none---> -ibm-mqseries 1414/udp # IBM MQSeries -ibm-mqseries 1414/tcp # IBM MQSeries -# Roger Meli -dbstar 1415/udp # DBStar -dbstar 1415/tcp # DBStar -# Jeffrey Millman -novell-lu6.2 1416/udp # Novell LU6.2 -novell-lu6.2 1416/tcp # Novell LU6.2 -# Peter Liu <--none---> -timbuktu-srv1 1417/udp # Timbuktu Service 1 Port -timbuktu-srv1 1417/tcp # Timbuktu Service 1 Port -timbuktu-srv2 1418/udp # Timbuktu Service 2 Port -timbuktu-srv2 1418/tcp # Timbuktu Service 2 Port -timbuktu-srv3 1419/udp # Timbuktu Service 3 Port -timbuktu-srv3 1419/tcp # Timbuktu Service 3 Port -timbuktu-srv4 1420/udp # Timbuktu Service 4 Port -timbuktu-srv4 1420/tcp # Timbuktu Service 4 Port -# Marc Epard -gandalf-lm 1421/udp # Gandalf License Manager -gandalf-lm 1421/tcp # Gandalf License Manager -# gilmer@gandalf.ca -autodesk-lm 1422/udp # Autodesk License Manager -autodesk-lm 1422/tcp # Autodesk License Manager -# David Ko -essbase 1423/udp # Essbase Arbor Software -essbase 1423/tcp # Essbase Arbor Software -hybrid 1424/udp # Hybrid Encryption Protocol -hybrid 1424/tcp # Hybrid Encryption Protocol -# Howard Hart -zion-lm 1425/udp # Zion Software License Manager -zion-lm 1425/tcp # Zion Software License Manager -# David Ferrero -sais 1426/udp # Satellite-data Acquisition System 1 -sais 1426/tcp # Satellite-data Acquisition System 1 -# Bill Taylor -mloadd 1427/udp # mloadd monitoring tool -mloadd 1427/tcp # mloadd monitoring tool -# Bob Braden -informatik-lm 1428/udp # Informatik License Manager -informatik-lm 1428/tcp # Informatik License Manager -# Harald Schlangmann -# -nms 1429/udp # Hypercom NMS -nms 1429/tcp # Hypercom NMS -tpdu 1430/udp # Hypercom TPDU -tpdu 1430/tcp # Hypercom TPDU -# Noor Chowdhury -rgtp 1431/udp # Reverse Gossip Transport -rgtp 1431/tcp # Reverse Gossip Transport -# Ian Jackson -blueberry-lm 1432/udp # Blueberry Software License Manager -blueberry-lm 1432/tcp # Blueberry Software License Manager -# Steve Beigel -ms-sql-s 1433/udp # Microsoft-SQL-Server -ms-sql-s 1433/tcp # Microsoft-SQL-Server -ms-sql-m 1434/udp # Microsoft-SQL-Monitor -ms-sql-m 1434/tcp # Microsoft-SQL-Monitor -# Peter Hussey -ibm-cics 1435/udp # IBM CICS -ibm-cics 1435/tcp # IBM CICS -# Geoff Meacock -saism 1436/udp # Satellite-data Acquisition System 2 -saism 1436/tcp # Satellite-data Acquisition System 2 -# Bill Taylor -tabula 1437/udp # Tabula -tabula 1437/tcp # Tabula -# Marcelo Einhorn -# -eicon-server 1438/udp # Eicon Security Agent/Server -eicon-server 1438/tcp # Eicon Security Agent/Server -eicon-x25 1439/udp # Eicon X25/SNA Gateway -eicon-x25 1439/tcp # Eicon X25/SNA Gateway -eicon-slp 1440/udp # Eicon Service Location Protocol -eicon-slp 1440/tcp # Eicon Service Location Protocol -# Pat Calhoun -cadis-1 1441/udp # Cadis License Management -cadis-1 1441/tcp # Cadis License Management -cadis-2 1442/udp # Cadis License Management -cadis-2 1442/tcp # Cadis License Management -# Todd Wichers -ies-lm 1443/udp # Integrated Engineering Software -ies-lm 1443/tcp # Integrated Engineering Software -# David Tong -marcam-lm 1444/udp # Marcam License Management -marcam-lm 1444/tcp # Marcam License Management -# Therese Hunt -proxima-lm 1445/udp # Proxima License Manager -proxima-lm 1445/tcp # Proxima License Manager -ora-lm 1446/udp # Optical Research Associates License Manager -ora-lm 1446/tcp # Optical Research Associates License Manager -apri-lm 1447/udp # Applied Parallel Research LM -apri-lm 1447/tcp # Applied Parallel Research LM -# Jim Dillon -oc-lm 1448/udp # OpenConnect License Manager -oc-lm 1448/tcp # OpenConnect License Manager -# Sue Barnhill -peport 1449/udp # PEport -peport 1449/tcp # PEport -# Qentin Neill -dwf 1450/udp # Tandem Distributed Workbench Facility -dwf 1450/tcp # Tandem Distributed Workbench Facility -# Mike Bert -infoman 1451/udp # IBM Information Management -infoman 1451/tcp # IBM Information Management -# Karen Burns <---none---> -gtegsc-lm 1452/udp # GTE Government Systems License Man -gtegsc-lm 1452/tcp # GTE Government Systems License Man -# Mike Gregory -genie-lm 1453/udp # Genie License Manager -genie-lm 1453/tcp # Genie License Manager -# Paul Applegate -interhdl_elmd 1454/udp # interHDL License Manager -interhdl_elmd 1454/tcp # interHDL License Manager -# Eli Sternheim eli@interhdl.com -esl-lm 1455/udp # ESL License Manager -esl-lm 1455/tcp # ESL License Manager -# Abel Chou -dca 1456/udp # DCA -dca 1456/tcp # DCA -# Jeff Garbers -valisys-lm 1457/udp # Valisys License Manager -valisys-lm 1457/tcp # Valisys License Manager -# Leslie Lincoln -nrcabq-lm 1458/udp # Nichols Research Corp. -nrcabq-lm 1458/tcp # Nichols Research Corp. -# Howard Cole -proshare1 1459/udp # Proshare Notebook Application -proshare1 1459/tcp # Proshare Notebook Application -proshare2 1460/udp # Proshare Notebook Application -proshare2 1460/tcp # Proshare Notebook Application -# Robin Kar -ibm_wrless_lan 1461/udp # IBM Wireless LAN -ibm_wrless_lan 1461/tcp # IBM Wireless LAN -# -world-lm 1462/udp # World License Manager -world-lm 1462/tcp # World License Manager -# Michael S Amirault -nucleus 1463/udp # Nucleus -nucleus 1463/tcp # Nucleus -# Venky Nagar -msl_lmd 1464/udp # MSL License Manager -msl_lmd 1464/tcp # MSL License Manager -# Matt Timmermans -pipes 1465/udp # Pipes Platform mfarlin@peerlogic.com -pipes 1465/tcp # Pipes Platform -# Mark Farlin -oceansoft-lm 1466/udp # Ocean Software License Manager -oceansoft-lm 1466/tcp # Ocean Software License Manager -# Randy Leonard -csdmbase 1467/udp # CSDMBASE -csdmbase 1467/tcp # CSDMBASE -csdm 1468/udp # CSDM -csdm 1468/tcp # CSDM -# Robert Stabl -aal-lm 1469/udp # Active Analysis Limited License Manager -aal-lm 1469/tcp # Active Analysis Limited License Manager -# David Snocken +44 (71)437-7009 -uaiact 1470/udp # Universal Analytics -uaiact 1470/tcp # Universal Analytics -# Mark R. Ludwig -csdmbase 1471/udp # csdmbase -csdmbase 1471/tcp # csdmbase -csdm 1472/udp # csdm -csdm 1472/tcp # csdm -# Robert Stabl -openmath 1473/udp # OpenMath -openmath 1473/tcp # OpenMath -# Garth Mayville -telefinder 1474/udp # Telefinder -telefinder 1474/tcp # Telefinder -# Jim White -taligent-lm 1475/udp # Taligent License Manager -taligent-lm 1475/tcp # Taligent License Manager -# Mark Sapsford -clvm-cfg 1476/udp # clvm-cfg -clvm-cfg 1476/tcp # clvm-cfg -# Eric Soderberg -ms-sna-server 1477/udp # ms-sna-server -ms-sna-server 1477/tcp # ms-sna-server -ms-sna-base 1478/udp # ms-sna-base -ms-sna-base 1478/tcp # ms-sna-base -# Gordon Mangione -dberegister 1479/udp # dberegister -dberegister 1479/tcp # dberegister -# Brian Griswold -pacerforum 1480/udp # PacerForum -pacerforum 1480/tcp # PacerForum -# Peter Caswell -airs 1481/udp # AIRS -airs 1481/tcp # AIRS -# Bruce Wilson, 905-771-6161 -miteksys-lm 1482/udp # Miteksys License Manager -miteksys-lm 1482/tcp # Miteksys License Manager -# Shane McRoberts -afs 1483/udp # AFS License Manager -afs 1483/tcp # AFS License Manager -# Michael R. Pizolato -confluent 1484/udp # Confluent License Manager -confluent 1484/tcp # Confluent License Manager -# James Greenfiel -lansource 1485/udp # LANSource -lansource 1485/tcp # LANSource -# Christopher Wells -nms_topo_serv 1486/udp # nms_topo_serv -nms_topo_serv 1486/tcp # nms_topo_serv -# Sylvia Siu -localinfosrvr 1487/udp # LocalInfoSrvr -localinfosrvr 1487/tcp # LocalInfoSrvr -# Brian Matthews -docstor 1488/udp # DocStor -docstor 1488/tcp # DocStor -# Brian Spears -dmdocbroker 1489/udp # dmdocbroker -dmdocbroker 1489/tcp # dmdocbroker -# Razmik Abnous -insitu-conf 1490/udp # insitu-conf -insitu-conf 1490/tcp # insitu-conf -# Paul Blacknell -anynetgateway 1491/udp # anynetgateway -anynetgateway 1491/tcp # anynetgateway -# Dan Poirier -stone-design-1 1492/udp # stone-design-1 -stone-design-1 1492/tcp # stone-design-1 -# Andrew Stone -netmap_lm 1493/udp # netmap_lm -netmap_lm 1493/tcp # netmap_lm -# Phillip Magson -ica 1494/udp # ica -ica 1494/tcp # ica -# John Richardson, Citrix Systems -cvc 1495/udp # cvc -cvc 1495/tcp # cvc -# Bill Davidson -liberty-lm 1496/udp # liberty-lm -liberty-lm 1496/tcp # liberty-lm -# Jim Rogers -rfx-lm 1497/udp # rfx-lm -rfx-lm 1497/tcp # rfx-lm -# Bill Bishop -sybase-sqlany 1498/udp # Sybase SQL Any -sybase-sqlany 1498/tcp # Sybase SQL Any -# Dave Neudoerffer -fhc 1499/udp # Federico Heinz Consultora -fhc 1499/tcp # Federico Heinz Consultora -# Federico Heinz -vlsi-lm 1500/udp # VLSI License Manager -vlsi-lm 1500/tcp # VLSI License Manager -# Shue-Lin Kuo -saiscm 1501/udp # Satellite-data Acquisition System 3 -saiscm 1501/tcp # Satellite-data Acquisition System 3 -# Bill Taylor -shivadiscovery 1502/udp # Shiva -shivadiscovery 1502/tcp # Shiva -# Jonathan Wenocur -imtc-mcs 1503/udp # Databeam -imtc-mcs 1503/tcp # Databeam -# Jim Johnston -evb-elm 1504/udp # EVB Software Engineering License Manager -evb-elm 1504/tcp # EVB Software Engineering License Manager -# B.G. Mahesh < mahesh@sett.com> -funkproxy 1505/udp # Funk Software, Inc. -funkproxy 1505/tcp # Funk Software, Inc. -# Robert D. Vincent -utcd 1506/udp # Universal Time daemon (utcd) -utcd 1506/tcp # Universal Time daemon (utcd) -# Walter Poxon -symplex 1507/udp # symplex -symplex 1507/tcp # symplex -# Mike Turley -diagmond 1508/udp # diagmond -diagmond 1508/tcp # diagmond -# Pete Moscatelli -robcad-lm 1509/udp # Robcad, Ltd. License Manager -robcad-lm 1509/tcp # Robcad, Ltd. License Manager -# Hindin Joseph -mvx-lm 1510/udp # Midland Valley Exploration Ltd. Lic. Man. -mvx-lm 1510/tcp # Midland Valley Exploration Ltd. Lic. Man. -# Neil Salter Laszlo -3l-l1 1511/udp # 3l-l1 -3l-l1 1511/tcp # 3l-l1 -# Ian A. Young -wins 1512/udp # Microsoft's Windows Internet Name Service -wins 1512/tcp # Microsoft's Windows Internet Name Service -# Pradeep Bahl -fujitsu-dtc 1513/udp # Fujitsu Systems Business of America, Inc -fujitsu-dtc 1513/tcp # Fujitsu Systems Business of America, Inc -fujitsu-dtcns 1514/udp # Fujitsu Systems Business of America, Inc -fujitsu-dtcns 1514/tcp # Fujitsu Systems Business of America, Inc -# Charles A. Higgins <75730.2257@compuserve.com> -ifor-protocol 1515/udp # ifor-protocol -ifor-protocol 1515/tcp # ifor-protocol -# Dr. R.P. Alston -vpad 1516/udp # Virtual Places Audio data -vpad 1516/tcp # Virtual Places Audio data -vpac 1517/udp # Virtual Places Audio control -vpac 1517/tcp # Virtual Places Audio control -vpvd 1518/udp # Virtual Places Video data -vpvd 1518/tcp # Virtual Places Video data -vpvc 1519/udp # Virtual Places Video control -vpvc 1519/tcp # Virtual Places Video control -# Avshalom Houri -atm-zip-office 1520/udp # atm zip office -atm-zip-office 1520/tcp # atm zip office -# Wilson Kwan -ncube-lm 1521/udp # nCube License Manager -ncube-lm 1521/tcp # nCube License Manager -# Maxine Yuen -ricardo-lm 1522/udp # Ricardo North America License Manager -ricardo-lm 1522/tcp # Ricardo North America License Manager -# Mike Flemming -cichild-lm 1523/udp # cichild -cichild-lm 1523/tcp # cichild -# Andy Burgess -ingreslock 1524/udp # ingres -ingreslock 1524/tcp # ingres -orasrv 1525/udp prospero-np # oracle -orasrv 1525/tcp prospero-np # oracle -pdap-np 1526/udp # Prospero Data Access Prot non-priv -pdap-np 1526/tcp # Prospero Data Access Prot non-priv -# B. Clifford Neuman -tlisrv 1527/udp # oracle -tlisrv 1527/tcp # oracle -mciautoreg 1528/udp # micautoreg -mciautoreg 1528/tcp # micautoreg -# John Klensin -coauthor 1529/udp # oracle -coauthor 1529/tcp # oracle -rap-service 1530/udp # rap-service -rap-service 1530/tcp # rap-service -rap-listen 1531/udp # rap-listen -rap-listen 1531/tcp # rap-listen -# Phil Servita -miroconnect 1532/udp # miroconnect -miroconnect 1532/tcp # miroconnect -# Michael Fischer +49 531 21 13 0 -virtual-places 1533/udp # Virtual Places Software -virtual-places 1533/tcp # Virtual Places Software -# Avshalom Houri -micromuse-lm 1534/udp # micromuse-lm -micromuse-lm 1534/tcp # micromuse-lm -# Adam Kerrison -ampr-info 1535/udp # ampr-info -ampr-info 1535/tcp # ampr-info -ampr-inter 1536/udp # ampr-inter -ampr-inter 1536/tcp # ampr-inter -# Rob Janssen -sdsc-lm 1537/udp # isi-lm -sdsc-lm 1537/tcp # isi-lm -# Len Wanger -3ds-lm 1538/udp # 3ds-lm -3ds-lm 1538/tcp # 3ds-lm -# Keith Trummel -intellistor-lm 1539/udp # Intellistor License Manager -intellistor-lm 1539/tcp # Intellistor License Manager -# Ron Vaughn -rds 1540/udp # rds -rds 1540/tcp # rds -rds2 1541/udp # rds2 -rds2 1541/tcp # rds2 -# Sudhakar Rajamannar -gridgen-elmd 1542/udp # gridgen-elmd -gridgen-elmd 1542/tcp # gridgen-elmd -# John R. Chawner +1 817 354-1004 -simba-cs 1543/udp # simba-cs -simba-cs 1543/tcp # simba-cs -# Betsy Alexander +1 604-681-4549 -aspeclmd 1544/udp # aspeclmd -aspeclmd 1544/tcp # aspeclmd -# V. Balaji -vistium-share 1545/udp # vistium-share -vistium-share 1545/tcp # vistium-share -# Allison Carleton -# -abbaccuray 1546/udp # abbaccuray -abbaccuray 1546/tcp # abbaccuray -# John Wendt 614-261-2000 -laplink 1547/udp # laplink -laplink 1547/tcp # laplink -# Michael Crawford -axon-lm 1548/udp # Axon License Manager -axon-lm 1548/tcp # Axon License Manager -# Mark Pearce < -shivasound 1549/udp # Shiva Sound -shivahose 1549/tcp # Shiva Hose -# Kin Chan -3m-image-lm 1550/udp # Image Storage license manager 3M Company -3m-image-lm 1550/tcp # Image Storage license manager 3M Company -# J. C. Canessa -hecmtl-db 1551/udp # HECMTL-DB -hecmtl-db 1551/tcp # HECMTL-DB -# Maxime Belanger -pciarray 1552/udp # pciarray -pciarray 1552/tcp # pciarray -# Ron Folk -sna-cs 1553/udp # sna-cs -sna-cs 1553/tcp # sna-cs -# Tony Sowter -caci-lm 1554/udp # CACI Products Company License Manager -caci-lm 1554/tcp # CACI Products Company License Manager -# Erik Blume -livelan 1555/udp # livelan -livelan 1555/tcp # livelan -# khedayat@roadrunner.pictel.com -ashwin 1556/udp # AshWin CI Tecnologies -ashwin 1556/tcp # AshWin CI Tecnologies -# Dave Neal -arbortext-lm 1557/udp # ArborText License Manager -arbortext-lm 1557/tcp # ArborText License Manager -# David J. Wilson -xingmpeg 1558/udp # xingmpeg -xingmpeg 1558/tcp # xingmpeg -# Howard Gordon -web2host 1559/udp # web2host -web2host 1559/tcp # web2host -# Stephen Johnson -asci-val 1560/udp # ASCI-RemoteSHADOW -asci-val 1560/tcp # ASCI-RemoteSHADOW -# Benjamin Rosenberg -facilityview 1561/udp # facilityview -facilityview 1561/tcp # facilityview -# Ed Green -pconnectmgr 1562/udp # pconnectmgr -pconnectmgr 1562/tcp # pconnectmgr -# Bob Kaiser -cadabra-lm 1563/udp # Cadabra License Manager -cadabra-lm 1563/tcp # Cadabra License Manager -# Arthur Castonguay -pay-per-view 1564/udp # Pay-Per-View -pay-per-view 1564/tcp # Pay-Per-View -# Brian Tung -winddlb 1565/udp # WinDD -winddlb 1565/tcp # WinDD -# Kelly Sims -corelvideo 1566/udp # CORELVIDEO -corelvideo 1566/tcp # CORELVIDEO -# Ming Poon -jlicelmd 1567/udp # jlicelmd -jlicelmd 1567/tcp # jlicelmd -# Christian Schormann <100410.3063@compuserve.com> -tsspmap 1568/udp # tsspmap -tsspmap 1568/tcp # tsspmap -# Paul W. Nelson -ets 1569/udp # ets -ets 1569/tcp # ets -# Carstein Seeberg -orbixd 1570/udp # orbixd -orbixd 1570/tcp # orbixd -# Bridget Walsh -rdb-dbs-disp 1571/udp # Oracle Remote Data Base -rdb-dbs-disp 1571/tcp # Oracle Remote Data Base -# -chip-lm 1572/udp # Chipcom License Manager -chip-lm 1572/tcp # Chipcom License Manager -# Jerry Natowitz -itscomm-ns 1573/udp # itscomm-ns -itscomm-ns 1573/tcp # itscomm-ns -# Rich Thompson -mvel-lm 1574/udp # mvel-lm -mvel-lm 1574/tcp # mvel-lm -# David Bisset -oraclenames 1575/udp # oraclenames -oraclenames 1575/tcp # oraclenames -# P.V.Shivkumar -moldflow-lm 1576/udp # moldflow-lm -moldflow-lm 1576/tcp # moldflow-lm -# Paul Browne -hypercube-lm 1577/udp # hypercube-lm -hypercube-lm 1577/tcp # hypercube-lm -# Christopher McLendon -jacobus-lm 1578/udp # Jacobus License Manager -jacobus-lm 1578/tcp # Jacobus License Manager -# Tony Cleveland -ioc-sea-lm 1579/udp # ioc-sea-lm -ioc-sea-lm 1579/tcp # ioc-sea-lm -# Paul Nelson -tn-tl-r2 1580/udp # tn-tl-r2 -tn-tl-r1 1580/tcp # tn-tl-r1 -# Ed Kress -mil-2045-47001 1581/udp # MIL-2045-47001 -mil-2045-47001 1581/tcp # MIL-2045-47001 -# Eric Whitehill -msims 1582/udp # MSIMS -msims 1582/tcp # MSIMS -# Glenn Olander -simbaexpress 1583/udp # simbaexpress -simbaexpress 1583/tcp # simbaexpress -# Betsy Alexander +1 604-681-4549 -tn-tl-fd2 1584/udp # tn-tl-fd2 -tn-tl-fd2 1584/tcp # tn-tl-fd2 -# Ed Kress -intv 1585/udp # intv -intv 1585/tcp # intv -# Dermot Tynand -ibm-abtact 1586/udp # ibm-abtact -ibm-abtact 1586/tcp # ibm-abtact -# Sandeep K. Singhal -pra_elmd 1587/udp # pra_elmd -pra_elmd 1587/tcp # pra_elmd -# Dennis Mastin -triquest-lm 1588/udp # triquest-lm -triquest-lm 1588/tcp # triquest-lm -# Nand Kumar -vqp 1589/udp # VQP -vqp 1589/tcp # VQP -# Keith McCloghrie -gemini-lm 1590/udp # gemini-lm -gemini-lm 1590/tcp # gemini-lm -# Tony Sawyer -ncpm-pm 1591/udp # ncpm-pm -ncpm-pm 1591/tcp # ncpm-pm -# Ted Power -commonspace 1592/udp # commonspace -commonspace 1592/tcp # commonspace -# Rob Chandhok -mainsoft-lm 1593/udp # mainsoft-lm -mainsoft-lm 1593/tcp # mainsoft-lm -# Anand Gangadharan -sixtrak 1594/udp # sixtrak -sixtrak 1594/tcp # sixtrak -# Bob Rennie -radio 1595/udp # radio -radio 1595/tcp # radio -radio-bc 1596/udp # radio-bc -radio-sm 1596/tcp # radio-sm -# Ken Chapman -orbplus-iiop 1597/udp # orbplus-iiop -orbplus-iiop 1597/tcp # orbplus-iiop -# Robert A. Kukura -picknfs 1598/udp # picknfs -picknfs 1598/tcp # picknfs -# John Lombardo -simbaservices 1599/udp # simbaservices -simbaservices 1599/tcp # simbaservices -# Betsy Alexander +1 604-681-4549 -issd 1600/udp # -issd 1600/tcp # -aas 1601/udp # aas -aas 1601/tcp # aas -# Bob Beard -inspect 1602/udp # inspect -inspect 1602/tcp # inspect -# Frank O'Neill -picodbc 1603/udp # pickodbc -picodbc 1603/tcp # pickodbc -# John Lombardo -icabrowser 1604/udp # icabrowser -icabrowser 1604/tcp # icabrowser -# Brad Pedersen -slp 1605/udp # Salutation Manager (Salutation Protocol) -slp 1605/tcp # Salutation Manager (Salutation Protocol) -slm-api 1606/udp # Salutation Manager (SLM-API) -slm-api 1606/tcp # Salutation Manager (SLM-API) -# Tohru Mori -stt 1607/udp # stt -stt 1607/tcp # stt -# Ryan Bolz -smart-lm 1608/udp # Smart Corp. License Manager -smart-lm 1608/tcp # Smart Corp. License Manager -# Connie Qiu -isysg-lm 1609/udp # isysg-lm -isysg-lm 1609/tcp # isysg-lm -# Adam Curtin -taurus-wh 1610/udp # taurus-wh -taurus-wh 1610/tcp # taurus-wh -# Jeff Moffatt -ill 1611/udp # Inter Library Loan -ill 1611/tcp # Inter Library Loan -# Niall Murphy -netbill-trans 1612/udp # NetBill Transaction Server -netbill-trans 1612/tcp # NetBill Transaction Server -netbill-keyrep 1613/udp # NetBill Key Repository -netbill-keyrep 1613/tcp # NetBill Key Repository -netbill-cred 1614/udp # NetBill Credential Server -netbill-cred 1614/tcp # NetBill Credential Server -netbill-auth 1615/udp # NetBill Authorization Server -netbill-auth 1615/tcp # NetBill Authorization Server -netbill-prod 1616/udp # NetBill Product Server -netbill-prod 1616/tcp # NetBill Product Server -# Marvin Sirbu -nimrod-agent 1617/udp # Nimrod Inter-Agent Communication -nimrod-agent 1617/tcp # Nimrod Inter-Agent Communication -# Charles Lynn -skytelnet 1618/udp # skytelnet -skytelnet 1618/tcp # skytelnet -# Byron Jones -xs-openstorage 1619/udp # xs-openstorage -xs-openstorage 1619/tcp # xs-openstorage -# XuiS Software Ltd. <100322.2376@compuserve.com> -faxportwinport 1620/udp # faxportwinport -faxportwinport 1620/tcp # faxportwinport -# Chris Wells -softdataphone 1621/udp # softdataphone -softdataphone 1621/tcp # softdataphone -# Dror Gill n -ontime 1622/udp # ontime -ontime 1622/tcp # ontime -# Keith Rhodes 810-559-5955 -jaleosnd 1623/udp # jaleosnd -jaleosnd 1623/tcp # jaleosnd -# Christian Schormann <100410.3063@compuserve.com> -udp-sr-port 1624/udp # udp-sr-port -udp-sr-port 1624/tcp # udp-sr-port -# Herb Jensen -svs-omagent 1625/udp # svs-omagent -svs-omagent 1625/tcp # svs-omagent -# Alberto Berlen -shockwave 1626/udp # Shockwave -shockwave 1626/tcp # Shockwave -# Sarah Allen -t128-gateway 1627/udp # T.128 Gateway -t128-gateway 1627/tcp # T.128 Gateway -# Phil May -lontalk-norm 1628/udp # LonTalk normal -lontalk-norm 1628/tcp # LonTalk normal -lontalk-urgnt 1629/udp # LonTalk urgent -lontalk-urgnt 1629/tcp # LonTalk urgent -# Dan Wing -oraclenet8cman 1630/udp # Oracle Net8 Cman -oraclenet8cman 1630/tcp # Oracle Net8 Cman -# Tong-Ming Lee -visitview 1631/udp # Visit view -visitview 1631/tcp # Visit view -# Tom Whittaker -pammratc 1632/udp # PAMMRATC -pammratc 1632/tcp # PAMMRATC -pammrpc 1633/udp # PAMMRPC -pammrpc 1633/tcp # PAMMRPC -# John Britton -loaprobe 1634/udp # Log On America Probe -loaprobe 1634/tcp # Log On America Probe -# James Tavares, Log On America -edb-server1 1635/udp # EDB Server 1 -edb-server1 1635/tcp # EDB Server 1 -# Carlos Portela -cncp 1636/udp # CableNet Control Protocol -cncp 1636/tcp # CableNet Control Protocol -cnap 1637/udp # CableNet Admin Protocol -cnap 1637/tcp # CableNet Admin Protocol -cnip 1638/udp # CableNet Info Protocol -cnip 1638/tcp # CableNet Info Protocol -# Damian Hamill -cert-initiator 1639/udp # cert-initiator -cert-initiator 1639/tcp # cert-initiator -cert-responder 1640/udp # cert-responder -cert-responder 1640/tcp # cert-responder -# Tom Markson -invision 1641/udp # InVision -invision 1641/tcp # InVision -# Christopher Davey -isis-am 1642/udp # isis-am -isis-am 1642/tcp # isis-am -isis-ambc 1643/udp # isis-ambc -isis-ambc 1643/tcp # isis-ambc -# Ken Chapman -saiseh 1644/tcp # Satellite-data Acquisition System 4 -# Bill Taylor -sightline 1645/udp # SightLine -sightline 1645/tcp # SightLine -# Stuart J. Newman -sa-msg-port 1646/udp # sa-msg-port -sa-msg-port 1646/tcp # sa-msg-port -# Eric Whitehill -rsap 1647/udp # rsap -rsap 1647/tcp # rsap -# Holger Reif -# -concurrent-lm 1648/udp # concurrent-lm -concurrent-lm 1648/tcp # concurrent-lm -# Maggie Brinsford -kermit 1649/udp # kermit -kermit 1649/tcp # kermit -# Frank da Cruz -nkd 1650/udp # nkd -nkd 1650/tcp # nkdn -shiva_confsrvr 1651/udp # shiva_confsrvr -shiva_confsrvr 1651/tcp # shiva_confsrvr -# Mike Horowitz -xnmp 1652/udp # xnmp -xnmp 1652/tcp # xnmp -# Ali Saleh -alphatech-lm 1653/udp # alphatech-lm -alphatech-lm 1653/tcp # alphatech-lm -# Joseph Hauk -stargatealerts 1654/udp # stargatealerts -stargatealerts 1654/tcp # stargatealerts -# Tim Coppernoll -# -dec-mbadmin 1655/udp # dec-mbadmin -dec-mbadmin 1655/tcp # dec-mbadmin -dec-mbadmin-h 1656/udp # dec-mbadmin-h -dec-mbadmin-h 1656/tcp # dec-mbadmin-h -# Nick Shipman -fujitsu-mmpdc 1657/udp # fujitsu-mmpdc -fujitsu-mmpdc 1657/tcp # fujitsu-mmpdc -# Katsumi Oomuro -sixnetudr 1658/udp # sixnetudr -sixnetudr 1658/tcp # sixnetudr -# Bob Rennie -sg-lm 1659/udp # Silicon Grail License Manager -sg-lm 1659/tcp # Silicon Grail License Manager -# William R Bishop -skip-mc-gikreq 1660/udp # skip-mc-gikreq -skip-mc-gikreq 1660/tcp # skip-mc-gikreq -# Tom Markson -netview-aix-1 1661/udp # netview-aix-1 -netview-aix-1 1661/tcp # netview-aix-1 -netview-aix-2 1662/udp # netview-aix-2 -netview-aix-2 1662/tcp # netview-aix-2 -netview-aix-3 1663/udp # netview-aix-3 -netview-aix-3 1663/tcp # netview-aix-3 -netview-aix-4 1664/udp # netview-aix-4 -netview-aix-4 1664/tcp # netview-aix-4 -netview-aix-5 1665/udp # netview-aix-5 -netview-aix-5 1665/tcp # netview-aix-5 -netview-aix-6 1666/udp # netview-aix-6 -netview-aix-6 1666/tcp # netview-aix-6 -netview-aix-7 1667/udp # netview-aix-7 -netview-aix-7 1667/tcp # netview-aix-7 -netview-aix-8 1668/udp # netview-aix-8 -netview-aix-8 1668/tcp # netview-aix-8 -netview-aix-9 1669/udp # netview-aix-9 -netview-aix-9 1669/tcp # netview-aix-9 -netview-aix-10 1670/udp # netview-aix-10 -netview-aix-10 1670/tcp # netview-aix-10 -netview-aix-11 1671/udp # netview-aix-11 -netview-aix-11 1671/tcp # netview-aix-11 -netview-aix-12 1672/udp # netview-aix-12 -netview-aix-12 1672/tcp # netview-aix-12 -# Martha Crisson -# -proshare-mc-1 1673/udp # Intel Proshare Multicast -proshare-mc-1 1673/tcp # Intel Proshare Multicast -proshare-mc-2 1674/udp # Intel Proshare Multicast -proshare-mc-2 1674/tcp # Intel Proshare Multicast -# Mark Lewis -pdp 1675/udp # Pacific Data Products -pdp 1675/tcp # Pacific Data Products -# Gary Morton -netcomm2 1676/udp # netcomm2 -netcomm1 1676/tcp # netcomm1 -# Bulent Kasman -groupwise 1677/udp # groupwise -groupwise 1677/tcp # groupwise -# Brent Bradshaw -prolink 1678/udp # prolink -prolink 1678/tcp # prolink -# Brian Abramson -darcorp-lm 1679/udp # darcorp-lm -darcorp-lm 1679/tcp # darcorp-lm -# -microcom-sbp 1680/udp # microcom-sbp -microcom-sbp 1680/tcp # microcom-sbp -# Boris B. Maiden -sd-elmd 1681/udp # sd-elmd -sd-elmd 1681/tcp # sd-elmd -# Bryan Otey -lanyon-lantern 1682/udp # lanyon-lantern -lanyon-lantern 1682/tcp # lanyon-lantern -# Robin Lewis -ncpm-hip 1683/udp # ncpm-hip -ncpm-hip 1683/tcp # ncpm-hip -# Ken Hearn -snaresecure 1684/udp # SnareSecure -snaresecure 1684/tcp # SnareSecure -# Marty Batchelder -n2nremote 1685/udp # n2nremote -n2nremote 1685/tcp # n2nremote -# Kin Chan -cvmon 1686/udp # cvmon -cvmon 1686/tcp # cvmon -# Carol Ann Krug -nsjtp-ctrl 1687/udp # nsjtp-ctrl -nsjtp-ctrl 1687/tcp # nsjtp-ctrl -nsjtp-data 1688/udp # nsjtp-data -nsjtp-data 1688/tcp # nsjtp-data -# Orazio Granato -firefox 1689/udp # firefox -firefox 1689/tcp # firefox -# Mark S. Edwards -ng-umds 1690/udp # ng-umds -ng-umds 1690/tcp # ng-umds -# Louis E. Simard <76400.3371@compuserve.com> -empire-empuma 1691/udp # empire-empuma -empire-empuma 1691/tcp # empire-empuma -# Bobby Krupczak -sstsys-lm 1692/udp # sstsys-lm -sstsys-lm 1692/tcp # sstsys-lm -# Yih-Wu Wang -rrirtr 1693/udp # rrirtr -rrirtr 1693/tcp # rrirtr -rrimwm 1694/udp # rrimwm -rrimwm 1694/tcp # rrimwm -rrilwm 1695/udp # rrilwm -rrilwm 1695/tcp # rrilwm -rrifmm 1696/udp # rrifmm -rrifmm 1696/tcp # rrifmm -rrisat 1697/udp # rrisat -rrisat 1697/tcp # rrisat -# Allen Briggs -rsvp-encap-1 1698/udp # RSVP-ENCAPSULATION-1 -rsvp-encap-1 1698/tcp # RSVP-ENCAPSULATION-1 -rsvp-encap-2 1699/udp # RSVP-ENCAPSULATION-2 -rsvp-encap-2 1699/tcp # RSVP-ENCAPSULATION-2 -# Bob Braden -mps-raft 1700/udp # mps-raft -mps-raft 1700/tcp # mps-raft -# Jason Leupen -l2f 1701/udp l2tp # l2f -l2f 1701/tcp l2tp # l2f -# Andy Valencia -deskshare 1702/udp # deskshare -deskshare 1702/tcp # deskshare -# Sarah Thompson cchou@zoom.com> -bcs-broker 1704/udp # bcs-broker -bcs-broker 1704/tcp # bcs-broker -# Andy Warner -slingshot 1705/udp # slingshot -slingshot 1705/tcp # slingshot -# Paul Groarke -jetform 1706/udp # jetform -jetform 1706/tcp # jetform -# gdeinsta -vdmplay 1707/udp # vdmplay -vdmplay 1707/tcp # vdmplay -# Vadim Lebedev -gat-lmd 1708/udp # gat-lmd -gat-lmd 1708/tcp # gat-lmd -# Igor Zaoutine -centra 1709/udp # centra -centra 1709/tcp # centra -# Drew Wolff -impera 1710/udp # impera -impera 1710/tcp # impera -# Stepehen Campbell -pptconference 1711/udp # pptconference -pptconference 1711/tcp # pptconference -# John Tafoya -registrar 1712/udp # resource monitoring service -registrar 1712/tcp # resource monitoring service -# Ron Lawson -conferencetalk 1713/udp # ConferenceTalk -conferencetalk 1713/tcp # ConferenceTalk -# George Kajos -sesi-lm 1714/udp # sesi-lm -sesi-lm 1714/tcp # sesi-lm -houdini-lm 1715/udp # houdini-lm -houdini-lm 1715/tcp # houdini-lm -# Paul Breslin -xmsg 1716/udp # xmsg -xmsg 1716/tcp # xmsg -# Mark E. Fogle -fj-hdnet 1717/udp # fj-hdnet -fj-hdnet 1717/tcp # fj-hdnet -# Manabu Makino -h323gatedisc 1718/udp # h323gatedisc -h323gatedisc 1718/tcp # h323gatedisc -h323gatestat 1719/udp # h323gatestat -h323gatestat 1719/tcp # h323gatestat -h323hostcall 1720/udp # h323hostcall -h323hostcall 1720/tcp # h323hostcall -# Jim Toga -caicci 1721/udp # caicci -caicci 1721/tcp # caicci -# Sylvia Scheuren -hks-lm 1722/udp # HKS License Manager -hks-lm 1722/tcp # HKS License Manager -# Michael Wood -pptp 1723/udp # pptp -pptp 1723/tcp # pptp -# Ken Crocker -csbphonemaster 1724/udp # csbphonemaster -csbphonemaster 1724/tcp # csbphonemaster -# Mark Kellerhuis -iden-ralp 1725/udp # iden-ralp -iden-ralp 1725/tcp # iden-ralp -# Chris Stanaway -iberiagames 1726/udp # IBERIAGAMES -iberiagames 1726/tcp # IBERIAGAMES -# Jose Luis <73374.313@compuserve.com> -winddx 1727/udp # winddx -winddx 1727/tcp # winddx -# Bill Andrews -telindus 1728/udp # TELINDUS -telindus 1728/tcp # TELINDUS -# Paul Pyck citydisc@euronet.nl> -roketz 1730/udp # roketz -roketz 1730/tcp # roketz -# Ahti Heinla -msiccp 1731/udp # MSICCP -msiccp 1731/tcp # MSICCP -# Max Morris -proxim 1732/udp # proxim -proxim 1732/tcp # proxim -# Srinivas N. Mogalapalli -siipat 1733/udp # SIMS - SIIPAT Protocol for Alarm Transmission -siipat 1733/tcp # SIMS - SIIPAT Protocol for Alarm Transmission -# Steve Ryckman -cambertx-lm 1734/udp # Camber Corporation License Management -cambertx-lm 1734/tcp # Camber Corporation License Management -# Jeannie Burleson -privatechat 1735/udp # PrivateChat -privatechat 1735/tcp # PrivateChat -# Louis E. Simard <76400.3371@CompuServe.COM> -street-stream 1736/udp # street-stream -street-stream 1736/tcp # street-stream -# Glenn Levitt -ultimad 1737/udp # ultimad -ultimad 1737/tcp # ultimad -# (Michael Lanzetta -gamegen1 1738/udp # GameGen1 -gamegen1 1738/tcp # GameGen1 -# Glen Pearson -webaccess 1739/udp # webaccess -webaccess 1739/tcp # webaccess -# Christian Saether -encore 1740/udp # encore -encore 1740/tcp # encore -# Stuart Button -cisco-net-mgmt 1741/udp # cisco-net-mgmt -cisco-net-mgmt 1741/tcp # cisco-net-mgmt -# John McCormack -3Com-nsd 1742/udp # 3Com-nsd -3Com-nsd 1742/tcp # 3Com-nsd -# Nitza Steinberg -cinegrfx-lm 1743/udp # Cinema Graphics License Manager -cinegrfx-lm 1743/tcp # Cinema Graphics License Manager -# Rodney Iwashina -ncpm-ft 1744/udp # ncpm-ft -ncpm-ft 1744/tcp # ncpm-ft -# Ken Hearn -remote-winsock 1745/udp # remote-winsock -remote-winsock 1745/tcp # remote-winsock -# Avi Nathan -ftrapid-1 1746/udp # ftrapid-1 -ftrapid-1 1746/tcp # ftrapid-1 -ftrapid-2 1747/udp # ftrapid-2 -ftrapid-2 1747/tcp # ftrapid-2 -# Richard J. Williams -oracle-em1 1748/udp # oracle-em1 -oracle-em1 1748/tcp # oracle-em1 -# Bob Purvy -aspen-services 1749/udp # aspen-services -aspen-services 1749/tcp # aspen-services -# Mark B. Hurst -sslp 1750/udp # Simple Socket Library's PortMaster -sslp 1750/tcp # Simple Socket Library's PortMaster -# Dr. Charles E. Campbell Jr. -# -swiftnet 1751/udp # SwiftNet -swiftnet 1751/tcp # SwiftNet -# Terry Lim -lofr-lm 1752/udp # Leap of Faith Research License Manager -lofr-lm 1752/tcp # Leap of Faith Research License Manager -# -translogic-lm 1753/udp # Translogic License Manager -translogic-lm 1753/tcp # Translogic License Manager -# Stan Dallas -oracle-em2 1754/udp # oracle-em2 -oracle-em2 1754/tcp # oracle-em2 -# Bob Purvy -ms-streaming 1755/udp # ms-streaming -ms-streaming 1755/tcp # ms-streaming -# Bret O'Rourke -capfast-lmd 1756/udp # capfast-lmd -capfast-lmd 1756/tcp # capfast-lmd -# Chuck Neal -cnhrp 1757/udp # cnhrp -cnhrp 1757/tcp # cnhrp -# William Stoye -tftp-mcast 1758/udp # tftp-mcast -tftp-mcast 1758/tcp # tftp-mcast -# Tom Emberson -spss-lm 1759/udp # SPSS License Manager -spss-lm 1759/tcp # SPSS License Manager -# Tex Hull -www-ldap-gw 1760/udp # www-ldap-gw -www-ldap-gw 1760/tcp # www-ldap-gw -# Nick Emery -cft-0 1761/udp # cft-0 -cft-0 1761/tcp # cft-0 -cft-1 1762/udp # cft-1 -cft-1 1762/tcp # cft-1 -cft-2 1763/udp # cft-2 -cft-2 1763/tcp # cft-2 -cft-3 1764/udp # cft-3 -cft-3 1764/tcp # cft-3 -cft-4 1765/udp # cft-4 -cft-4 1765/tcp # cft-4 -cft-5 1766/udp # cft-5 -cft-5 1766/tcp # cft-5 -cft-6 1767/udp # cft-6 -cft-6 1767/tcp # cft-6 -cft-7 1768/udp # cft-7 -cft-7 1768/tcp # cft-7 -# Martine Marchand 16 1 46 59 24 84 -bmc-net-adm 1769/udp # bmc-net-adm -bmc-net-adm 1769/tcp # bmc-net-adm -# Cameron Haight -bmc-net-svc 1770/udp # bmc-net-svc -bmc-net-svc 1770/tcp # bmc-net-svc -# Cameron Haight bmc-net-svc -vaultbase 1771/udp # vaultbase -vaultbase 1771/tcp # vaultbase -# Jose A. Sesin -essweb-gw 1772/udp # EssWeb Gateway -essweb-gw 1772/tcp # EssWeb Gateway -# Bob Nattenberg -kmscontrol 1773/udp # KMSControl -kmscontrol 1773/tcp # KMSControl -# Roy Chastain -global-dtserv 1774/udp # global-dtserv -global-dtserv 1774/tcp # global-dtserv -# Nicholas Davies -# 1775/tcp -femis 1776/udp # Federal Emergency Management Information System -femis 1776/tcp # Federal Emergency Management Information System -# Larry Gerhardstein -powerguardian 1777/udp # powerguardian -powerguardian 1777/tcp # powerguardian -# Charles Bennett -prodigy-intrnet 1778/udp # prodigy-internet -prodigy-intrnet 1778/tcp # prodigy-internet -# Bob Dedrick -pharmasoft 1779/udp # pharmasoft -pharmasoft 1779/tcp # pharmasoft -# Ola Strandberg -dpkeyserv 1780/udp # dpkeyserv -dpkeyserv 1780/tcp # dpkeyserv -# Yasunari Gon Yamasita -answersoft-lm 1781/udp # answersoft-lm -answersoft-lm 1781/tcp # answersoft-lm -# James A. Brewster -hp-hcip 1782/udp # hp-hcip -hp-hcip 1782/tcp # hp-hcip -# Allen Baker -# 1783 Decomissioned Port 04/14/00, ms -# -finle-lm 1784/udp # Finle License Manager -finle-lm 1784/tcp # Finle License Manager -# Dongling Wang -windlm 1785/udp # Wind River Systems License Manager -windlm 1785/tcp # Wind River Systems License Manager -# Will Dere -funk-logger 1786/udp # funk-logger -funk-logger 1786/tcp # funk-logger -funk-license 1787/udp # funk-license -funk-license 1787/tcp # funk-license -# Cimarron Boozer -# Eric Wilde -psmond 1788/udp # psmond -psmond 1788/tcp # psmond -# Will Golson -hello 1789/udp # hello -hello 1789/tcp # hello -# D. J. Bernstein -nmsp 1790/udp # Narrative Media Streaming Protocol -nmsp 1790/tcp # Narrative Media Streaming Protocol -# Paul Santinelli, Jr. -ea1 1791/udp # EA1 -ea1 1791/tcp # EA1 -# Kirk MacLean -ibm-dt-2 1792/udp # ibm-dt-2 -ibm-dt-2 1792/tcp # ibm-dt-2 -# Sam Borman -rsc-robot 1793/udp # rsc-robot -rsc-robot 1793/tcp # rsc-robot -# Andrew Jay Schneider -cera-bcm 1794/udp # cera-bcm -cera-bcm 1794/tcp # cera-bcm -# Leo Moesgaard -dpi-proxy 1795/udp # dpi-proxy -dpi-proxy 1795/tcp # dpi-proxy -# Charles Gordon -vocaltec-admin 1796/udp # Vocaltec Server Administration -vocaltec-admin 1796/tcp # Vocaltec Server Administration -# Scott Petrack -uma 1797/udp # UMA -uma 1797/tcp # UMA -# Martin Kirk -etp 1798/udp # Event Transfer Protocol -etp 1798/tcp # Event Transfer Protocol -# Mike Wray -netrisk 1799/udp # NETRISK -netrisk 1799/tcp # NETRISK -# Kevin Green -ansys-lm 1800/udp # ANSYS-License manager -ansys-lm 1800/tcp # ANSYS-License manager -# Suzanne Lorrin -msmq 1801/udp # Microsoft Message Que -msmq 1801/tcp # Microsoft Message Que -# Amnon Horowitz -concomp1 1802/udp # ConComp1 -concomp1 1802/tcp # ConComp1 -# Ed Vincent <@edv@concomp.com> -hp-hcip-gwy 1803/udp # HP-HCIP-GWY -hp-hcip-gwy 1803/tcp # HP-HCIP-GWY -# Allen Baker -enl 1804/udp # ENL -enl 1804/tcp # ENL -# Brian Olson -enl-name 1805/udp # ENL-Name -enl-name 1805/tcp # ENL-Name -# Brian Olson -musiconline 1806/udp # Musiconline -musiconline 1806/tcp # Musiconline -# Craig Weeks -fhsp 1807/udp # Fujitsu Hot Standby Protocol -fhsp 1807/tcp # Fujitsu Hot Standby Protocol -# Eiki Iwata (eiki@nd.net.fujitsu.co.jp> -oracle-vp2 1808/udp # Oracle-VP2 -oracle-vp2 1808/tcp # Oracle-VP2 -# Craig Fowler -oracle-vp1 1809/udp # Oracle-VP1 -oracle-vp1 1809/tcp # Oracle-VP1 -# Craig Fowler -jerand-lm 1810/udp # Jerand License Manager -jerand-lm 1810/tcp # Jerand License Manager -# Robert Monat -scientia-sdb 1811/udp # Scientia-SDB -scientia-sdb 1811/tcp # Scientia-SDB -# Ian Miller -radius 1812/udp # RADIUS -radius 1812/tcp # RADIUS -# Carl Rigney -radius-acct 1813/udp # RADIUS Accounting -radius-acct 1813/tcp # RADIUS Accounting -# Carl Rigney -tdp-suite 1814/udp # TDP Suite -tdp-suite 1814/tcp # TDP Suite -# Rob Lockhart -mmpft 1815/udp # MMPFT -mmpft 1815/tcp # MMPFT -# Ralf Muckenhirn -# -harp 1816/udp # HARP -harp 1816/tcp # HARP -# Bjorn Chambless -rkb-oscs 1817/udp # RKB-OSCS -rkb-oscs 1817/tcp # RKB-OSCS -# Robert Kevin Breton -etftp 1818/udp # Enhanced Trivial File Transfer Protocol -etftp 1818/tcp # Enhanced Trivial File Transfer Protocol -# William Polites -plato-lm 1819/udp # Plato License Manager -plato-lm 1819/tcp # Plato License Manager -# Mark Morris -mcagent 1820/udp # mcagent -mcagent 1820/tcp # mcagent -# Ryoichi Shinohara -donnyworld 1821/udp # donnyworld -donnyworld 1821/tcp # donnyworld -# Don Oliver -es-elmd 1822/udp # es-elmd -es-elmd 1822/tcp # es-elmd -# David Duncan -unisys-lm 1823/udp # Unisys Natural Language License Manager -unisys-lm 1823/tcp # Unisys Natural Language License Manager -# Raymond A. Diedrichs -metrics-pas 1824/udp # metrics-pas -metrics-pas 1824/tcp # metrics-pas -# Tom Haapanen -direcpc-video 1825/udp # DirecPC Video -direcpc-video 1825/tcp # DirecPC Video -# Chris Kerrigan -ardt 1826/udp # ARDT -ardt 1826/tcp # ARDT -# Mike Goddard -asi 1827/udp # ASI -asi 1827/tcp # ASI -# Bob Tournoux -itm-mcell-u 1828/udp # itm-mcell-u -itm-mcell-u 1828/tcp # itm-mcell-u -# Miles O'Neal -optika-emedia 1829/udp # Optika eMedia -optika-emedia 1829/tcp # Optika eMedia -# Daryle DeBalski -net8-cman 1830/udp # Oracle Net8 CMan Admin -net8-cman 1830/tcp # Oracle Net8 CMan Admin -# Shuvayu Kanjilal -myrtle 1831/udp # Myrtle -myrtle 1831/tcp # Myrtle -# Ron Achin -tht-treasure 1832/udp # ThoughtTreasure -tht-treasure 1832/tcp # ThoughtTreasure -# Erik Mueller -udpradio 1833/udp # udpradio -udpradio 1833/tcp # udpradio -# Guus Sliepen -ardusuni 1834/udp # ARDUS Unicast -ardusuni 1834/tcp # ARDUS Unicast -ardusmul 1835/udp # ARDUS Multicast -ardusmul 1835/tcp # ARDUS Multicast -# Toshikatsu Ito -ste-smsc 1836/udp # ste-smsc -ste-smsc 1836/tcp # ste-smsc -# Tom Snauwaert -csoft1 1837/udp # csoft1 -csoft1 1837/tcp # csoft1 -# John Coll -talnet 1838/udp # TALNET -talnet 1838/tcp # TALNET -# Aaron Lav -netopia-vo1 1839/udp # netopia-vo1 -netopia-vo1 1839/tcp # netopia-vo1 -netopia-vo2 1840/udp # netopia-vo2 -netopia-vo2 1840/tcp # netopia-vo2 -netopia-vo3 1841/udp # netopia-vo3 -netopia-vo3 1841/tcp # netopia-vo3 -netopia-vo4 1842/udp # netopia-vo4 -netopia-vo4 1842/tcp # netopia-vo4 -netopia-vo5 1843/udp # netopia-vo5 -netopia-vo5 1843/tcp # netopia-vo5 -# Marc Epard -direcpc-dll 1844/udp # DirecPC-DLL -direcpc-dll 1844/tcp # DirecPC-DLL -# Chris Kerrigan -altalink 1845/udp # altalink -altalink 1845/tcp # altalink -# Alberto Raydan -tunstall-pnc 1846/udp # Tunstall PNC -tunstall-pnc 1846/tcp # Tunstall PNC -# Robert M. Moore -slp-notify 1847/udp # SLP Notification -slp-notify 1847/tcp # SLP Notification -# James Kempf -fjdocdist 1848/udp # fjdocdist -fjdocdist 1848/tcp # fjdocdist -# Yuichi Ohiwa -alpha-sms 1849/udp # ALPHA-SMS -alpha-sms 1849/tcp # ALPHA-SMS -# Benjamin Grimm -gsi 1850/udp # GSI -gsi 1850/tcp # GSI -# William Mullaney -ctcd 1851/udp # ctcd -ctcd 1851/tcp # ctcd -# John Ryan -virtual-time 1852/udp # Virtual Time -virtual-time 1852/tcp # Virtual Time -# Angie S. Morner -vids-avtp 1853/udp # VIDS-AVTP -vids-avtp 1853/tcp # VIDS-AVTP -# Sascha Kuemmel -buddy-draw 1854/udp # Buddy Draw -buddy-draw 1854/tcp # Buddy Draw -# Marvin Shin -fiorano-rtrsvc 1855/udp # Fiorano RtrSvc -fiorano-rtrsvc 1855/tcp # Fiorano RtrSvc -fiorano-msgsvc 1856/udp # Fiorano MsgSvc -fiorano-msgsvc 1856/tcp # Fiorano MsgSvc -# Albert Holt -datacaptor 1857/udp # DataCaptor -datacaptor 1857/tcp # DataCaptor -# Steven M. Forrester -privateark 1858/udp # PrivateArk -privateark 1858/tcp # PrivateArk -# Ronen Zoran -gammafetchsvr 1859/udp # Gamma Fetcher Server -gammafetchsvr 1859/tcp # Gamma Fetcher Server -# Cnaan Aviv -sunscalar-svc 1860/udp # SunSCALAR Services -sunscalar-svc 1860/tcp # SunSCALAR Services -# Sanjay Radia -lecroy-vicp 1861/udp # LeCroy VICP -lecroy-vicp 1861/tcp # LeCroy VICP -# Anthony Cake -techra-server 1862/udp # techra-server -techra-server 1862/tcp # techra-server -# Roy Lyseng -msnp 1863/udp # MSNP -msnp 1863/tcp # MSNP -# William Lai -paradym-31port 1864/udp # Paradym 31 Port -paradym-31port 1864/tcp # Paradym 31 Port -# David Wooden -entp 1865/udp # ENTP -entp 1865/tcp # ENTP -# Seiko Epson -swrmi 1866/udp # swrmi -swrmi 1866/tcp # swrmi -# Jun Yoshii -udrive 1867/udp # UDRIVE -udrive 1867/tcp # UDRIVE -# Robby Walker -viziblebrowser 1868/udp # VizibleBrowser -viziblebrowser 1868/tcp # VizibleBrowser -# Jimmy Talbot -yestrader 1869/udp # YesTrader -yestrader 1869/tcp # YesTrader -# Robert Bryan -sunscalar-dns 1870/udp # SunSCALAR DNS Service -sunscalar-dns 1870/tcp # SunSCALAR DNS Service -# Sanjay Radia -canocentral0 1871/udp # Cano Central 0 -canocentral0 1871/tcp # Cano Central 0 -canocentral1 1872/udp # Cano Central 1 -canocentral1 1872/tcp # Cano Central 1 -# Mark McNamara -fjmpjps 1873/udp # Fjmpjps -fjmpjps 1873/tcp # Fjmpjps -fjswapsnp 1874/udp # Fjswapsnp -fjswapsnp 1874/tcp # Fjswapsnp -# Y. Ohiwa -westell-stats 1875/udp # westell stats -westell-stats 1875/tcp # westell stats -# Thomas McCabe -ewcappsrv 1876/udp # ewcappsrv -ewcappsrv 1876/tcp # ewcappsrv -# Howard Yin -hp-webqosdb 1877/udp # hp-webqosdb -hp-webqosdb 1877/tcp # hp-webqosdb -# Kim Scott -drmsmc 1878/udp # drmsmc -drmsmc 1878/tcp # drmsmc -# Katsuhiko Abe -nettgain-nms 1879/udp # NettGain NMS -nettgain-nms 1879/tcp # NettGain NMS -# Dr. Yair Shapira -vsat-control 1880/udp # Gilat VSAT Control -vsat-control 1880/tcp # Gilat VSAT Control -# Yariv Kaplan -ibm-mqseries2 1881/udp # IBM WebSphere MQ -ibm-mqseries2 1881/tcp # IBM WebSphere MQ -# Richard Maxwell -ecsqdmn 1882/udp # ecsqdmn -ecsqdmn 1882/tcp # ecsqdmn -# Paul Wissmiller -ibm-mqisdp 1883/udp # IBM MQSeries SCADA -ibm-mqisdp 1883/tcp # IBM MQSeries SCADA -# Andy Stanford-Clark -idmaps 1884/udp # Internet Distance Map Svc -idmaps 1884/tcp # Internet Distance Map Svc -# Sugih Jamim -vrtstrapserver 1885/udp # Veritas Trap Server -vrtstrapserver 1885/tcp # Veritas Trap Server -# Russell Thrasher -leoip 1886/udp # Leonardo over IP -leoip 1886/tcp # Leonardo over IP -# Dietmar Finkler -filex-lport 1887/udp # FileX Listening Port -filex-lport 1887/tcp # FileX Listening Port -# Megan Woods -ncconfig 1888/udp # NC Config Port -ncconfig 1888/tcp # NC Config Port -# Simon Parker -unify-adapter 1889/udp # Unify Web Adapter Service -unify-adapter 1889/tcp # Unify Web Adapter Service -# Duane Gibson -wilkenlistener 1890/udp # wilkenListener -wilkenlistener 1890/tcp # wilkenListener -# Wilken GmbH -childkey-notif 1891/udp # ChildKey Notification -childkey-notif 1891/tcp # ChildKey Notification -childkey-ctrl 1892/udp # ChildKey Control -childkey-ctrl 1892/tcp # ChildKey Control -# Ivan Berardinelli -elad 1893/udp # ELAD Protocol -elad 1893/tcp # ELAD Protocol -# Franco Milan -o2server-port 1894/udp # O2Server Port -o2server-port 1894/tcp # O2Server Port -# Tim Howard -##### Microsoft (unoffically) using 1895 ##### -b-novative-ls 1896/udp # b-novative license server -b-novative-ls 1896/tcp # b-novative license server -# Matthias Riese -metaagent 1897/udp # MetaAgent -metaagent 1897/tcp # MetaAgent -# Stephane Vinsot -cymtec-port 1898/udp # Cymtec secure management -cymtec-port 1898/tcp # Cymtec secure management -# Michael Mester -mc2studios 1899/udp # MC2Studios -mc2studios 1899/tcp # MC2Studios -# Michael Coon -ssdp 1900/udp # SSDP -ssdp 1900/tcp # SSDP -# Yaron Goland -fjicl-tep-a 1901/udp # Fujitsu ICL Terminal Emulator Program A -fjicl-tep-a 1901/tcp # Fujitsu ICL Terminal Emulator Program A -# Bob Lyon -fjicl-tep-b 1902/udp # Fujitsu ICL Terminal Emulator Program B -fjicl-tep-b 1902/tcp # Fujitsu ICL Terminal Emulator Program B -# Bob Lyon -linkname 1903/udp # Local Link Name Resolution -linkname 1903/tcp # Local Link Name Resolution -# Dan Harrington -fjicl-tep-c 1904/udp # Fujitsu ICL Terminal Emulator Program C -fjicl-tep-c 1904/tcp # Fujitsu ICL Terminal Emulator Program C -# Bob Lyon -sugp 1905/udp # Secure UP.Link Gateway Protocol -sugp 1905/tcp # Secure UP.Link Gateway Protocol -# Peter King -tpmd 1906/udp # TPortMapperReq -tpmd 1906/tcp # TPortMapperReq -# Sheila Devins -intrastar 1907/udp # IntraSTAR -intrastar 1907/tcp # IntraSTAR -# Peter Schoenberger -dawn 1908/udp # Dawn -dawn 1908/tcp # Dawn -# Michael Crawford -global-wlink 1909/udp # Global World Link -global-wlink 1909/tcp # Global World Link -# Nicholas Davies -ultrabac 1910/udp # UltraBac Software communications port -ultrabac 1910/tcp # UltraBac Software communications port -# Paul Bunn -mtp 1911/udp # Starlight Networks Multimedia Transport Protocol -mtp 1911/tcp # Starlight Networks Multimedia Transport Protocol -# Bruce Lieberman -rhp-iibp 1912/udp # rhp-iibp -rhp-iibp 1912/tcp # rhp-iibp -# George Nachman -# Tom Lake -armadp 1913/udp # armadp -armadp 1913/tcp # armadp -# Kevin Welton -elm-momentum 1914/udp # Elm-Momentum -elm-momentum 1914/tcp # Elm-Momentum -# Willie Wu -facelink 1915/udp # FACELINK -facelink 1915/tcp # FACELINK -# J.H. Hermans -persona 1916/udp # Persoft Persona -persona 1916/tcp # Persoft Persona -# Tom Spidell -noagent 1917/udp # nOAgent -noagent 1917/tcp # nOAgent -# Martin Bestmann -can-nds 1918/udp # Candle Directory Service - NDS -can-nds 1918/tcp # Candle Directory Service - NDS -can-dch 1919/udp # Candle Directory Service - DCH -can-dch 1919/tcp # Candle Directory Service - DCH -can-ferret 1920/udp # Candle Directory Service - FERRET -can-ferret 1920/tcp # Candle Directory Service - FERRET -# Dannis Yang -noadmin 1921/udp # NoAdmin -noadmin 1921/tcp # NoAdmin -# Martin Bestmann -tapestry 1922/udp # Tapestry -tapestry 1922/tcp # Tapestry -# Ken Oliver -spice 1923/udp # SPICE -spice 1923/tcp # SPICE -# Nicholas Chua -xiip 1924/udp # XIIP -xiip 1924/tcp # XIIP -# Alain Robert -discovery-port 1925/udp # Surrogate Discovery Port -discovery-port 1925/tcp # Surrogate Discovery Port -# Keith Thompson -egs 1926/udp # Evolution Game Server -egs 1926/tcp # Evolution Game Server -# Simon Butcher -videte-cipc 1927/udp # Videte CIPC Port -videte-cipc 1927/tcp # Videte CIPC Port -# Videte IT -emsd-port 1928/udp # Expnd Maui Srvr Dscovr -emsd-port 1928/tcp # Expnd Maui Srvr Dscovr -# Edo Yahav -bandwiz-system 1929/udp # Bandwiz System - Server -bandwiz-system 1929/tcp # Bandwiz System - Server -# Joseph Weihs -driveappserver 1930/udp # Drive AppServer -driveappserver 1930/tcp # Drive AppServer -# Andrew Johnson -# -amdsched 1931/udp # AMD SCHED -amdsched 1931/tcp # AMD SCHED -# Michael Walsh -ctt-broker 1932/udp # CTT Broker -ctt-broker 1932/tcp # CTT Broker -# Jens Edlund -xmapi 1933/udp # IBM LM MT Agent -xmapi 1933/tcp # IBM LM MT Agent -xaapi 1934/udp # IBM LM Appl Agent -xaapi 1934/tcp # IBM LM Appl Agent -# Helga Wolin -macromedia-fcs 1935/udp # Macromedia Flash Communications server MX -macromedia-fcs 1935/tcp # Macromedia Flash Communications Server MX -# Pritham Shetty -jetcmeserver 1936/udp # JetCmeServer Server Port -jetcmeserver 1936/tcp # JetCmeServer Server Port -jwserver 1937/udp # JetVWay Server Port -jwserver 1937/tcp # JetVWay Server Port -jwclient 1938/udp # JetVWay Client Port -jwclient 1938/tcp # JetVWay Client Port -jvserver 1939/udp # JetVision Server Port -jvserver 1939/tcp # JetVision Server Port -jvclient 1940/udp # JetVision Client Port -jvclient 1940/tcp # JetVision Client Port -# Stephen Tsun -dic-aida 1941/udp # DIC-Aida -dic-aida 1941/tcp # DIC-Aida -# Frans S.C. Witte -res 1942/udp # Real Enterprise Service -res 1942/tcp # Real Enterprise Service -# Bob Janssen -beeyond-media 1943/udp # Beeyond Media -beeyond-media 1943/tcp # Beeyond Media -# Bob Deblier -close-combat 1944/udp # close-combat -close-combat 1944/tcp # close-combat -# David Hua -dialogic-elmd 1945/udp # dialogic-elmd -dialogic-elmd 1945/tcp # dialogic-elmd -# Roger Kay -tekpls 1946/udp # tekpls -tekpls 1946/tcp # tekpls -# Brian Abramson -hlserver 1947/udp # hlserver -hlserver 1947/tcp # hlserver -# Michael Zzunke -eye2eye 1948/udp # eye2eye -eye2eye 1948/tcp # eye2eye -# Trevor Bell -ismaeasdaqlive 1949/udp # ISMA Easdaq Live -ismaeasdaqlive 1949/tcp # ISMA Easdaq Live -ismaeasdaqtest 1950/udp # ISMA Easdaq Test -ismaeasdaqtest 1950/tcp # ISMA Easdaq Test -# Stephen Dunne -bcs-lmserver 1951/udp # bcs-lmserver -bcs-lmserver 1951/tcp # bcs-lmserver -# Andy Warner -mpnjsc 1952/udp # mpnjsc -mpnjsc 1952/tcp # mpnjsc -# Takenori Miyahara -rapidbase 1953/udp # Rapid Base -rapidbase 1953/tcp # Rapid Base -# Antoni Wolski -abr-basic 1954/udp # ABR-Basic Data -abr-basic 1954/tcp # ABR-Basic Data -abr-secure 1955/udp # ABR-Secure Data -abr-secure 1955/tcp # ABR-Secure Data -# Aero9 - Graham Wooden -vrtl-vmf-ds 1956/udp # Vertel VMF DS -vrtl-vmf-ds 1956/tcp # Vertel VMF DS -# Alan Akahoshi -unix-status 1957/udp # unix-status -unix-status 1957/tcp # unix-status -# Thomas Erskine -dxadmind 1958/udp # CA Administration Daemon -dxadmind 1958/tcp # CA Administration Daemon -# John Birrell -simp-all 1959/udp # SIMP Channel -simp-all 1959/tcp # SIMP Channel -# Tim Hunnewell -nasmanager 1960/udp # Merit DAC NASmanager -nasmanager 1960/tcp # Merit DAC NASmanager -# Richard S. Conto -bts-appserver 1961/udp # BTS APPSERVER -bts-appserver 1961/tcp # BTS APPSERVER -# Carl Obsorn -biap-mp 1962/udp # BIAP-MP -biap-mp 1962/tcp # BIAP-MP -# Chuck Shotton -webmachine 1963/udp # WebMachine -webmachine 1963/tcp # WebMachine -# Tim Jowers -solid-e-engine 1964/udp # SOLID E ENGINE -solid-e-engine 1964/tcp # SOLID E ENGINE -# Ari Valtanen -tivoli-npm 1965/udp # Tivoli NPM -tivoli-npm 1965/tcp # Tivoli NPM -# Ivana Cuozzo -slush 1966/udp # Slush -slush 1966/tcp # Slush -# Damien Miller -sns-quote 1967/udp # SNS Quote -sns-quote 1967/tcp # SNS Quote -# Robert Ellman -lipsinc 1968/udp # LIPSinc -lipsinc 1968/tcp # LIPSinc -lipsinc1 1969/udp # LIPSinc 1 -lipsinc1 1969/tcp # LIPSinc 1 -# Robert Armington -netop-rc 1970/udp # NetOp Remote Control -netop-rc 1970/tcp # NetOp Remote Control -netop-school 1971/udp # NetOp School -netop-school 1971/tcp # NetOp School -# NetOp Technical Support -intersys-cache 1972/udp # Cache -intersys-cache 1972/tcp # Cache -# Mark Hanson -dlsrap 1973/udp # Data Link Switching Remote Access Protocol -dlsrap 1973/tcp # Data Link Switching Remote Access Protocol -# Steve T. Chiang -drp 1974/udp # DRP -drp 1974/tcp # DRP -# Richard Alan Johnson -tcoflashagent 1975/udp # TCO Flash Agent -tcoflashagent 1975/tcp # TCO Flash Agent -tcoregagent 1976/udp # TCO Reg Agent -tcoregagent 1976/tcp # TCO Reg Agent -tcoaddressbook 1977/udp # TCO Address Book -tcoaddressbook 1977/tcp # TCO Address Book -# Allan Panitch -unisql 1978/udp # UniSQL -unisql 1978/tcp # UniSQL -unisql-java 1979/udp # UniSQL Java -unisql-java 1979/tcp # UniSQL Java -# Keith Yarbrough -pearldoc-xact 1980/udp # PearlDoc XACT -pearldoc-xact 1980/tcp # PearlDoc XACT -# Chris Vertonghen -p2pq 1981/udp # p2pQ -p2pq 1981/tcp # p2pQ -# Warren Alexander -estamp 1982/udp # Evidentiary Timestamp -estamp 1982/tcp # Evidentiary Timestamp -# Todd Glassey -lhtp 1983/udp # Loophole Test Protocol -lhtp 1983/tcp # Loophole Test Protocol -# Kade Hansson -bb 1984/udp # BB -bb 1984/tcp # BB -# Sean MacGuire -hsrp 1985/udp # Hot Standby Router Protocol -hsrp 1985/tcp # Hot Standby Router Protocol -# Phil Morton -licensedaemon 1986/udp # cisco license management -licensedaemon 1986/tcp # cisco license management -tr-rsrb-p1 1987/udp # cisco RSRB Priority 1 port -tr-rsrb-p1 1987/tcp # cisco RSRB Priority 1 port -tr-rsrb-p2 1988/udp # cisco RSRB Priority 2 port -tr-rsrb-p2 1988/tcp # cisco RSRB Priority 2 port -tr-rsrb-p3 1989/udp # cisco RSRB Priority 3 port -tr-rsrb-p3 1989/tcp # cisco RSRB Priority 3 port -# The following entry records an unassigned but widespread use -mshnet 1989/udp # MHSnet system -mshnet 1989/tcp # MHSnet system -# Bob Kummerfeld -stun-p1 1990/udp # cisco STUN Priority 1 port -stun-p1 1990/tcp # cisco STUN Priority 1 port -stun-p2 1991/udp # cisco STUN Priority 2 port -stun-p2 1991/tcp # cisco STUN Priority 2 port -stun-p3 1992/udp # cisco STUN Priority 3 port -stun-p3 1992/tcp # cisco STUN Priority 3 port -# The following entry records an unassigned but widespread use -ipsendmsg 1992/udp # IPsendmsg -ipsendmsg 1992/tcp # IPsendmsg -# Bob Kummerfeld -snmp-tcp-port 1993/udp # cisco SNMP TCP port -snmp-tcp-port 1993/tcp # cisco SNMP TCP port -stun-port 1994/udp # cisco serial tunnel port -stun-port 1994/tcp # cisco serial tunnel port -perf-port 1995/udp # cisco perf port -perf-port 1995/tcp # cisco perf port -tr-rsrb-port 1996/udp # cisco Remote SRB port -tr-rsrb-port 1996/tcp # cisco Remote SRB port -gdp-port 1997/udp # cisco Gateway Discovery Protocol -gdp-port 1997/tcp # cisco Gateway Discovery Protocol -x25-svc-port 1998/udp # cisco X.25 service (XOT) -x25-svc-port 1998/tcp # cisco X.25 service (XOT) -tcp-id-port 1999/udp # cisco identification port -tcp-id-port 1999/tcp # cisco identification port -# -callbook 2000/udp # callbook -callbook 2000/tcp # callbook -# Devon Bowen -wizard 2001/udp # curry -dc 2001/tcp # -globe 2002/udp # -globe 2002/tcp # -emce 2004/udp # CCWS mm conf -mailbox 2004/tcp # -oracle 2005/udp # -berknet 2005/tcp # -raid-cc 2006/udp # raid -invokator 2006/tcp # -raid-am 2007/udp # -dectalk 2007/tcp # -terminaldb 2008/udp # -conf 2008/tcp # -whosockami 2009/udp # -news 2009/tcp # -pipe_server 2010/udp # -search 2010/tcp # -servserv 2011/udp # -raid-cc 2011/tcp # raid -raid-ac 2012/udp # -ttyinfo 2012/tcp # -raid-cd 2013/udp # -raid-am 2013/tcp # -raid-sf 2014/udp # -troff 2014/tcp # -raid-cs 2015/udp # -cypress 2015/tcp # -bootserver 2016/udp # -bootserver 2016/tcp # -bootclient 2017/udp # -cypress-stat 2017/tcp # -rellpack 2018/udp # -terminaldb 2018/tcp # -about 2019/udp # -whosockami 2019/tcp # -xinupageserver 2020/udp # -xinupageserver 2020/tcp # -xinuexpansion1 2021/udp # -servexec 2021/tcp # -xinuexpansion2 2022/udp # -down 2022/tcp # -xinuexpansion3 2023/udp # -xinuexpansion3 2023/tcp # -xinuexpansion4 2024/udp # -xinuexpansion4 2024/tcp # -xribs 2025/udp # -ellpack 2025/tcp # -scrabble 2026/udp # -scrabble 2026/tcp # -shadowserver 2027/udp # -shadowserver 2027/tcp # -submitserver 2028/udp # -submitserver 2028/tcp # -# 2029 Unassigned -device2 2030/udp # -device2 2030/tcp # -# 2031 Unassigned -blackboard 2032/udp # -blackboard 2032/tcp # -glogger 2033/udp # -glogger 2033/tcp # -scoremgr 2034/udp # -scoremgr 2034/tcp # -imsldoc 2035/udp # -imsldoc 2035/tcp # -# 2036 Unassigned -p2plus 2037/udp # P2plus Application Server -p2plus 2037/tcp # P2plus Application Server -# Thomas Boerkel -objectmanager 2038/udp # -objectmanager 2038/tcp # -# 2039 Unassigned -lam 2040/udp # -lam 2040/tcp # -interbase 2041/udp # -interbase 2041/tcp # -isis 2042/udp # isis -isis 2042/tcp # isis -isis-bcast 2043/udp # isis-bcast -isis-bcast 2043/tcp # isis-bcast -# Ken Chapman -rimsl 2044/udp # -rimsl 2044/tcp # -cdfunc 2045/udp # -cdfunc 2045/tcp # -sdfunc 2046/udp # -sdfunc 2046/tcp # -dls 2047/udp # -dls 2047/tcp # -dls-monitor 2048/udp # -dls-monitor 2048/tcp # -# <== NOTE Conflict on 2049 ! -shilp 2049/udp nfs # -shilp 2049/tcp nfs # -# Brent Callaghan -av-emb-config 2050/udp # Avaya EMB Config Port -av-emb-config 2050/tcp # Avaya EMB Config Port -# John Yeager -epnsdp 2051/udp # EPNSDP -epnsdp 2051/tcp # EPNSDP -# Hiroyasu Ogata -clearvisn 2052/udp # clearVisn Services Port -clearvisn 2052/tcp # clearVisn Services Port -# Dave Lyons -lot105-ds-upd 2053/udp # Lot105 DSuper Updates -lot105-ds-upd 2053/tcp # Lot105 DSuper Updates -# Piers Scannell -weblogin 2054/udp # Weblogin Port -weblogin 2054/tcp # Weblogin Port -# Diego Saravia -iop 2055/udp # Iliad-Odyssey Protocol -iop 2055/tcp # Iliad-Odyssey Protocol -# Bruce Lueckenhoff -omnisky 2056/udp # OmniSky Port -omnisky 2056/tcp # OmniSky Port -# Oren Hurvitz -rich-cp 2057/udp # Rich Content Protocol -rich-cp 2057/tcp # Rich Content Protocol -# Ronen Vainish -newwavesearch 2058/udp # NewWaveSearchables RMI -newwavesearch 2058/tcp # NewWaveSearchables RMI -# Thomas Kerkau -bmc-messaging 2059/udp # BMC Messaging Service -bmc-messaging 2059/tcp # BMC Messaging Service -# Roger Huebner -teleniumdaemon 2060/udp # Telenium Daemon IF -teleniumdaemon 2060/tcp # Telenium Daemon IF -# Nick Woronuk -netmount 2061/udp # NetMount -netmount 2061/tcp # NetMount -# Alex Oberlander -icg-swp 2062/udp # ICG SWP Port -icg-swp 2062/tcp # ICG SWP Port -icg-bridge 2063/udp # ICG Bridge Port -icg-bridge 2063/tcp # ICG Bridge Port -icg-iprelay 2064/udp # ICG IP Relay Port -icg-iprelay 2064/tcp # ICG IP Relay Port -# Steve Quintana -dlsrpn 2065/udp # Data Link Switch Read Port Number -dlsrpn 2065/tcp # Data Link Switch Read Port Number -# Amir Peless -# 2066 Unassigned -dlswpn 2067/udp # Data Link Switch Write Port Number -dlswpn 2067/tcp # Data Link Switch Write Port Number -# Amir Peless -avauthsrvprtcl 2068/udp # Avocent AuthSrv Protocol -avauthsrvprtcl 2068/tcp # Avocent AuthSrv Protocol -# Steven W. Clark -event-port 2069/udp # HTTP Event Port -event-port 2069/tcp # HTTP Event Port -# Larry Emlich -ah-esp-encap 2070/udp # AH and ESP Encapsulated in UDP packet -ah-esp-encap 2070/tcp # AH and ESP Encapsulated in UDP packet -# Amy Weaver -acp-port 2071/udp # Axon Control Protocol -acp-port 2071/tcp # Axon Control Protocol -# Christiaan Simons -msync 2072/udp # GlobeCast mSync -msync 2072/tcp # GlobeCast mSync -# Piers Scannell -gxs-data-port 2073/udp # DataReel Database Socket -gxs-data-port 2073/tcp # DataReel Database Socket -# Douglas M. Gaer -vrtl-vmf-sa 2074/udp # Vertel VMF SA -vrtl-vmf-sa 2074/tcp # Vertel VMF SA -# Alan Akahoshi -newlixengine 2075/udp # Newlix ServerWare Engine -newlixengine 2075/tcp # Newlix ServerWare Engine -newlixconfig 2076/udp # Newlix JSPConfig -newlixconfig 2076/tcp # Newlix JSPConfig -# Jean-Serge Gagnon -trellisagt 2077/udp # TrelliSoft Agent -trellisagt 2077/tcp # TrelliSoft Agent -trellissvr 2078/udp # TrelliSoft Server -trellissvr 2078/tcp # TrelliSoft Server -# Justin R. Bendich -idware-router 2079/udp # IDWARE Router Port -idware-router 2079/tcp # IDWARE Router Port -# Zdenek Kolba -autodesk-nlm 2080/udp # Autodesk NLM (FLEXlm) -autodesk-nlm 2080/tcp # Autodesk NLM (FLEXlm) -# Greg Suppes -kme-trap-port 2081/udp # KME PRINTER TRAP PORT -kme-trap-port 2081/tcp # KME PRINTER TRAP PORT -# Masakatsu Matsuo -infowave 2082/udp # Infowave Mobiltiy Server -infowave 2082/tcp # Infowave Mobility Server -# Kaz Kylheku -# 2083-2085 Unassigned -gnunet 2086/udp # GNUnet -gnunet 2086/tcp # GNUnet -# Christian Grothoff October 2002 -eli 2087/udp # ELI - Event Logging Integration -eli 2087/tcp # ELI - Event Logging Integration -# Maya Zimerman -# 2088 Unassigned -sep 2089/udp # Security Encapsulation Protocol - SEP -sep 2089/tcp # Security Encapsulation Protocol - SEP -# Maya Zimerman -lrp 2090/udp # Load Report Protocol -lrp 2090/tcp # Load Report Protocol -# Amir Peless -prp 2091/udp # PRP -prp 2091/tcp # PRP -# Amir Peless -descent3 2092/udp # Descent 3 -descent3 2092/tcp # Descent 3 -# Kevin Bentley -nbx-cc 2093/udp # NBX CC -nbx-cc 2093/tcp # NBX CC -nbx-au 2094/udp # NBX AU -nbx-au 2094/tcp # NBX AU -nbx-ser 2095/udp # NBX SER -nbx-ser 2095/tcp # NBX SER -nbx-dir 2096/udp # NBX DIR -nbx-dir 2096/tcp # NBX DIR -# Henry Houh -jetformpreview 2097/udp # Jet Form Preview -jetformpreview 2097/tcp # Jet Form Preview -# Zygmunt Wiercioch -dialog-port 2098/udp # Dialog Port -dialog-port 2098/tcp # Dialog Port -# Joseph Mathew -h2250-annex-g 2099/udp # H.225.0 Annex G -h2250-annex-g 2099/tcp # H.225.0 Annex G -# Gur Kimchi -amiganetfs 2100/udp # Amiga Network Filesystem -amiganetfs 2100/tcp # Amiga Network Filesystem -# Rudi Chiarito -rtcm-sc104 2101/udp # rtcm-sc104 -rtcm-sc104 2101/tcp # rtcm-sc104 -# Wolfgang Rupprecht -zephyr-srv 2102/udp # Zephyr server -zephyr-srv 2102/tcp # Zephyr server -zephyr-clt 2103/udp # Zephyr serv-hm connection -zephyr-clt 2103/tcp # Zephyr serv-hm connection -zephyr-hm 2104/udp # Zephyr hostmanager -zephyr-hm 2104/tcp # Zephyr hostmanager -# Greg Hudson -minipay 2105/udp # MiniPay -minipay 2105/tcp # MiniPay -# Amir Herzberg -mzap 2106/udp # MZAP -mzap 2106/tcp # MZAP -# Dave Thaler -bintec-admin 2107/udp # BinTec Admin -bintec-admin 2107/tcp # BinTec Admin -# Thomas Schmidt -comcam 2108/udp # Comcam -comcam 2108/tcp # Comcam -# Don Gilbreath -ergolight 2109/udp # Ergolight -ergolight 2109/tcp # Ergolight -# Jindra Ryvola -umsp 2110/udp # UMSP -umsp 2110/tcp # UMSP -# Alexander Bogdanov -dsatp 2111/udp # DSATP -dsatp 2111/tcp # DSATP -# Ralph Beck -idonix-metanet 2112/udp # Idonix MetaNet -idonix-metanet 2112/tcp # Idonix MetaNet -# Paul Harrison -hsl-storm 2113/udp # HSL StoRM -hsl-storm 2113/tcp # HSL StoRM -# Jost Faganel -newheights 2114/udp # NEWHEIGHTS -newheights 2114/tcp # NEWHEIGHTS -# Michael Levy -kdm 2115/udp # Key Distribution Manager -kdm 2115/tcp # Key Distribution Manager -# Mike Little -ccowcmr 2116/udp # CCOWCMR -ccowcmr 2116/tcp # CCOWCMR -# Mark Morwood -mentaclient 2117/udp # MENTACLIENT -mentaclient 2117/tcp # MENTACLIENT -mentaserver 2118/udp # MENTASERVER -mentaserver 2118/tcp # MENTASERVER -# Ilan Shlosberg -gsigatekeeper 2119/udp # GSIGATEKEEPER -gsigatekeeper 2119/tcp # GSIGATEKEEPER -# Steve Tuecke -qencp 2120/udp # Quick Eagle Networks CP -qencp 2120/tcp # Quick Eagle Networks CP -# Santa Dasu -scientia-ssdb 2121/udp # SCIENTIA-SSDB -scientia-ssdb 2121/tcp # SCIENTIA-SSDB -# Ian Miller -caupc-remote 2122/udp # CauPC Remote Control -caupc-remote 2122/tcp # CauPC Remote Control -# Environics Oy -gtp-control 2123/udp # GTP-Control Plane (3GPP) -gtp-control 2123/tcp # GTP-Control Plane (3GPP) -# Alessio Casati -elatelink 2124/udp # ELATELINK -elatelink 2124/tcp # ELATELINK -# Tim Lawrence -lockstep 2125/udp # LOCKSTEP -lockstep 2125/tcp # LOCKSTEP -# Karl Forster -pktcable-cops 2126/udp # PktCable-COPS -pktcable-cops 2126/tcp # PktCable-COPS -# Glenn Russell -index-pc-wb 2127/udp # INDEX-PC-WB -index-pc-wb 2127/tcp # INDEX-PC-WB -# James David Fisher -net-steward 2128/udp # Net Steward Control -net-steward 2128/tcp # Net Steward Control -# Martin Norman -cs-live 2129/udp # cs-live.com -cs-live 2129/tcp # cs-live.com -# Matt Lachance -swc-xds 2130/udp # SWC-XDS -swc-xds 2130/tcp # SWC-XDS -# Peter Zurich -avantageb2b 2131/udp # Avantageb2b -avantageb2b 2131/tcp # Avantageb2b -# Avi Software -avail-epmap 2132/udp # AVAIL-EPMAP -avail-epmap 2132/tcp # AVAIL-EPMAP -# Mark Armstrong -zymed-zpp 2133/udp # ZYMED-ZPP -zymed-zpp 2133/tcp # ZYMED-ZPP -# Gregg Welker -avenue 2134/udp # AVENUE -avenue 2134/tcp # AVENUE -# Jason Cater -gris 2135/udp # Grid Resource Information Server -gris 2135/tcp # Grid Resource Information Server -# Steve Tuecke -appworxsrv 2136/udp # APPWORXSRV -appworxsrv 2136/tcp # APPWORXSRV -# Fred McLain -connect 2137/udp # CONNECT -connect 2137/tcp # CONNECT -# Reid Ligon -unbind-cluster 2138/udp # UNBIND-CLUSTER -unbind-cluster 2138/tcp # UNBIND-CLUSTER -# Francois Harvey -ias-auth 2139/udp # IAS-AUTH -ias-auth 2139/tcp # IAS-AUTH -ias-reg 2140/udp # IAS-REG -ias-reg 2140/tcp # IAS-REG -ias-admind 2141/udp # IAS-ADMIND -ias-admind 2141/tcp # IAS-ADMIND -# Baiju V. Patel -tdm-over-ip 2142/udp # TDM-OVER-IP -tdm-over-ip 2142/tcp # TDM-OVER-IP -# Tal Gilad -lv-jc 2143/udp # Live Vault Job Control -lv-jc 2143/tcp # Live Vault Job Control -lv-ffx 2144/udp # Live Vault Fast Object Transfer -lv-ffx 2144/tcp # Live Vault Fast Object Transfer -lv-pici 2145/udp # Live Vault Remote Diagnostic Console Support -lv-pici 2145/tcp # Live Vault Remote Diagnostic Console Support -lv-not 2146/udp # Live Vault Admin Event Notification -lv-not 2146/tcp # Live Vault Admin Event Notification -lv-auth 2147/udp # Live Vault Authentication -lv-auth 2147/tcp # Live Vault Authentication -# Ted Hess -veritas-ucl 2148/udp # VERITAS UNIVERSAL COMMUNICATION LAYER -veritas-ucl 2148/tcp # VERITAS UNIVERSAL COMMUNICATION LAYER -# Songlin Ren -acptsys 2149/udp # ACPTSYS -acptsys 2149/tcp # ACPTSYS -# Michael Lekias -dynamic3d 2150/udp # DYNAMIC3D -dynamic3d 2150/tcp # DYNAMIC3D -# Tobias Wegner -docent 2151/udp # DOCENT -docent 2151/tcp # DOCENT -# Hali Lindbloom -gtp-user 2152/udp # GTP-User Plane (3GPP) -gtp-user 2152/tcp # GTP-User Plane (3GPP) -# Alessio Casati -# 2153-2158 Unassigned -gdbremote 2159/udp # GDB Remote Debug Port -gdbremote 2159/tcp # GDB Remote Debug Port -# Nigel Stephens -apc-2160 2160/udp # APC 2160 -apc-2160 2160/tcp # APC 2160 -# American Power Conversion -apc-2161 2161/udp # APC 2161 -apc-2161 2161/tcp # APC 2161 -# American Power Conversion -navisphere 2162/udp # Navisphere -navisphere 2162/tcp # Navisphere -navisphere-sec 2163/udp # Navisphere Secure -navisphere-sec 2163/tcp # Navisphere Secure -# Andreas Bauer -ddns-v3 2164/udp # Dynamic DNS Version 3 -ddns-v3 2164/tcp # Dynamic DNS Version 3 -# Alan Yates -x-bone-api 2165/udp # X-Bone API -x-bone-api 2165/tcp # X-Bone API -# Joe Touch -iwserver 2166/udp # iwserver -iwserver 2166/tcp # iwserver -# Fred Surr -raw-serial 2167/udp # Raw Async Serial Link -raw-serial 2167/tcp # Raw Async Serial Link -# Benjamin Green -# 2168-2179 Unassigned -mc-gt-srv 2180/udp # Millicent Vendor Gateway Server -mc-gt-srv 2180/tcp # Millicent Vendor Gateway Server -# Steve Glassman -eforward 2181/udp # eforward -eforward 2181/tcp # eforward -# Greg Pringle -# 2182-2189 Unassigned -tivoconnect 2190/udp # TiVoConnect Beacon -tivoconnect 2190/tcp # TiVoConnect Beacon -# Jeffrey J. Peters August 2002 -tvbus 2191/udp # TvBus Messaging -tvbus 2191/tcp # TvBus Messaging -# Brian W. Beach January 2003 -# 2192-2199 Unassigned -ici 2200/udp # ICI -ici 2200/tcp # ICI -# Brent Hines -ats 2201/udp # Advanced Training System Program -ats 2201/tcp # Advanced Training System Program -# (Need contact info) -imtc-map 2202/udp # Int. Multimedia Teleconferencing Cosortium -imtc-map 2202/tcp # Int. Multimedia Teleconferencing Cosortium -# Pat Galvin -kali 2213/udp # Kali -kali 2213/tcp # Kali -# Jay Cotton -netiq 2220/udp # NetIQ End2End -netiq 2220/tcp # NetIQ End2End -# Gary Weichinger -rockwell-csp1 2221/udp # Rockwell CSP1 -rockwell-csp1 2221/tcp # Rockwell CSP1 -rockwell-csp2 2222/udp # Rockwell CSP2 -rockwell-csp2 2222/tcp # Rockwell CSP2 -rockwell-csp3 2223/udp # Rockwell CSP3 -rockwell-csp3 2223/tcp # Rockwell CSP3 -# Brian Batke -# -ivs-video 2232/udp # IVS Video default -ivs-video 2232/tcp # IVS Video default -# Thierry Turletti -infocrypt 2233/udp # INFOCRYPT -infocrypt 2233/tcp # INFOCRYPT -# Erica Liu -directplay 2234/udp # DirectPlay -directplay 2234/tcp # DirectPlay -# Ajay Jindal -sercomm-wlink 2235/udp # Sercomm-WLink -sercomm-wlink 2235/tcp # Sercomm-WLink -# Melinda Tsao -nani 2236/udp # Nani -nani 2236/tcp # Nani -# Steve Benoit -optech-port1-lm 2237/udp # Optech Port1 License Manager -optech-port1-lm 2237/tcp # Optech Port1 License Manager -# Gerard Cannie -aviva-sna 2238/udp # AVIVA SNA SERVER -aviva-sna 2238/tcp # AVIVA SNA SERVER -# Vick Keshishian -imagequery 2239/udp # Image Query -imagequery 2239/tcp # Image Query -# Charles Jacobs -recipe 2240/udp # RECIPe -recipe 2240/tcp # RECIPe -# Charlie Limoges -ivsd 2241/udp # IVS Daemon -ivsd 2241/tcp # IVS Daemon -# Thierry Turletti -# -foliocorp 2242/udp # Folio Remote Server -foliocorp 2242/tcp # Folio Remote Server -# Pat Mcgowan -magicom 2243/udp # Magicom Protocol -magicom 2243/tcp # Magicom Protocol -# Yossi Appleboum -nmsserver 2244/udp # NMS Server -nmsserver 2244/tcp # NMS Server -# Dmitry Krasnonosenkikh -# -hao 2245/udp # HaO -hao 2245/tcp # HaO -# Panic Ride -pc-mta-addrmap 2246/udp # PacketCable MTA Addr Map -pc-mta-addrmap 2246/tcp # PacketCable MTA Addr Map -# Dave Maxwell -# 2247 Unassigned -ums 2248/udp # User Management Service -ums 2248/tcp # User Management Service -# Andrew Crockford -# -rfmp 2249/udp # RISO File Manager Protocol -rfmp 2249/tcp # RISO File Manager Protocol -# Shinji Yamanaka -remote-collab 2250/udp # remote-collab -remote-collab 2250/tcp # remote-collab -# Richard Walters -dif-port 2251/udp # Distributed Framework Port -dif-port 2251/tcp # Distributed Framework Port -# Sebastien Lambla -njenet-ssl 2252/udp # NJENET using SSL -njenet-ssl 2252/tcp # NJENET using SSL -# Hans U Schmidt -dtv-chan-req 2253/udp # DTV Channel Request -dtv-chan-req 2253/tcp # DTV Channel Request -# Richard Hodges -seispoc 2254/udp # Seismic P.O.C. Port -seispoc 2254/tcp # Seismic P.O.C. Port -# Robert Reimiller -vrtp 2255/udp # VRTP - ViRtue Transfer Protocol -vrtp 2255/tcp # VRTP - ViRtue Transfer Protocol -# Max Fudim -# 2256-2259 Unassigned -apc-2260 2260/udp # APC 2260 -apc-2260 2260/tcp # APC 2260 -# American Power Conversion February 2002 -# 2261-2278 Unassigned -xmquery 2279/udp # xmquery -xmquery 2279/tcp # xmquery -# Niels Christiansen -lnvpoller 2280/udp # LNVPOLLER -lnvpoller 2280/tcp # LNVPOLLER -lnvconsole 2281/udp # LNVCONSOLE -lnvconsole 2281/tcp # LNVCONSOLE -lnvalarm 2282/udp # LNVALARM -lnvalarm 2282/tcp # LNVALARM -lnvstatus 2283/udp # LNVSTATUS -lnvstatus 2283/tcp # LNVSTATUS -lnvmaps 2284/udp # LNVMAPS -lnvmaps 2284/tcp # LNVMAPS -lnvmailmon 2285/udp # LNVMAILMON -lnvmailmon 2285/tcp # LNVMAILMON -# John Payne -nas-metering 2286/udp # NAS-Metering -nas-metering 2286/tcp # NAS-Metering -# Steven Sawkins -dna 2287/udp # DNA -dna 2287/tcp # DNA -# Tung Nguyen -netml 2288/udp # NETML -netml 2288/tcp # NETML -# Jochen Hansmeyer -# 2289-2293 Unassigned -konshus-lm 2294/udp # Konshus License Manager (FLEX) -konshus-lm 2294/tcp # Konshus License Manager (FLEX) -# Francois Painchaud -advant-lm 2295/udp # Advant License Manager -advant-lm 2295/tcp # Advant License Manager -# Lars-Goran Magnusson -# -theta-lm 2296/udp # Theta License Manager (Rainbow) -theta-lm 2296/tcp # Theta License Manager (Rainbow) -# David Thompson -d2k-datamover1 2297/udp # D2K DataMover 1 -d2k-datamover1 2297/tcp # D2K DataMover 1 -d2k-datamover2 2298/udp # D2K DataMover 2 -d2k-datamover2 2298/tcp # D2K DataMover 2 -# Eric Lan -pc-telecommute 2299/udp # PC Telecommute -pc-telecommute 2299/tcp # PC Telecommute -# John Daniel Bonamico -cvmmon 2300/udp # CVMMON -cvmmon 2300/tcp # CVMMON -# Roger Kumpf -cpq-wbem 2301/udp # Compaq HTTP -cpq-wbem 2301/tcp # Compaq HTTP -# Scott Shaffer -binderysupport 2302/udp # Bindery Support -binderysupport 2302/tcp # Bindery Support -# Narasimha Rao N. -proxy-gateway 2303/udp # Proxy Gateway -proxy-gateway 2303/tcp # Proxy Gateway -# Paul Funk -attachmate-uts 2304/udp # Attachmate UTS -attachmate-uts 2304/tcp # Attachmate UTS -# George Gianelos -mt-scaleserver 2305/udp # MT ScaleServer -mt-scaleserver 2305/tcp # MT ScaleServer -# Paul Glaubitz -tappi-boxnet 2306/udp # TAPPI BoxNet -tappi-boxnet 2306/tcp # TAPPI BoxNet -# Richard Spartz -pehelp 2307/udp # pehelp -pehelp 2307/tcp # pehelp -# Jens Kilian -sdhelp 2308/udp # sdhelp -sdhelp 2308/tcp # sdhelp -# Annette Klecha -sdserver 2309/udp # SD Server -sdserver 2309/tcp # SD Server -sdclient 2310/udp # SD Client -sdclient 2310/tcp # SD Client -# Jeurgen Broesamle -messageservice 2311/udp # Message Service -messageservice 2311/tcp # Message Service -# No contact Listed -iapp 2313/udp # IAPP (Inter Access Point Protocol) -iapp 2313/tcp # IAPP (Inter Access Point Protocol) -# Henri Moelard -cr-websystems 2314/udp # CR WebSystems -cr-websystems 2314/tcp # CR WebSystems -# Robin Giese -precise-sft 2315/udp # Precise Sft. -precise-sft 2315/tcp # Precise Sft. -# Michael Landwehr -sent-lm 2316/udp # SENT License Manager -sent-lm 2316/tcp # SENT License Manager -# Pisharath Krishnan -attachmate-g32 2317/udp # Attachmate G32 -attachmate-g32 2317/tcp # Attachmate G32 -# Bryce Bhatnagar -cadencecontrol 2318/udp # Cadence Control -cadencecontrol 2318/tcp # Cadence Control -# Buck Caldwell -infolibria 2319/udp # InfoLibria -infolibria 2319/tcp # InfoLibria -# Chris Chiotasso -siebel-ns 2320/udp # Siebel NS -siebel-ns 2320/tcp # Siebel NS -# Gilberto Arnaiz -rdlap 2321/udp # RDLAP -rdlap 2321/tcp # RDLAP -# Robert Wiebe -ofsd 2322/udp # ofsd -ofsd 2322/tcp # ofsd -3d-nfsd 2323/udp # 3d-nfsd -3d-nfsd 2323/tcp # 3d-nfsd -# Mike Sherrill -cosmocall 2324/udp # Cosmocall -cosmocall 2324/tcp # Cosmocall -# Steve Dellutri -designspace-lm 2325/udp # Design Space License Management -designspace-lm 2325/tcp # Design Space License Management -# Suzanne Lorrin -idcp 2326/udp # IDCP -idcp 2326/tcp # IDCP -# Keisokugiken Corp. -xingcsm 2327/udp # xingcsm -xingcsm 2327/tcp # xingcsm -# Dave Spencer -netrix-sftm 2328/udp # Netrix SFTM -netrix-sftm 2328/tcp # Netrix SFTM -# Garrett Herschleb -nvd 2329/udp # NVD -nvd 2329/tcp # NVD -# Peter Weyman -tscchat 2330/udp # TSCCHAT -tscchat 2330/tcp # TSCCHAT -# Mike Jackson -agentview 2331/udp # AGENTVIEW -agentview 2331/tcp # AGENTVIEW -# Ram Iyer -rcc-host 2332/udp # RCC Host -rcc-host 2332/tcp # RCC Host -# Martin Shoemaker -snapp 2333/udp # SNAPP -snapp 2333/tcp # SNAPP -# Kevin Osborn -ace-client 2334/udp # ACE Client Auth -ace-client 2334/tcp # ACE Client Auth -ace-proxy 2335/udp # ACE Proxy -ace-proxy 2335/tcp # ACE Proxy -# Riaz Zolfonoon -appleugcontrol 2336/udp # Apple UG Control -appleugcontrol 2336/tcp # Apple UG Control -# Gene Tyacke -ideesrv 2337/udp # ideesrv -ideesrv 2337/tcp # ideesrv -# Marazzi -norton-lambert 2338/udp # Norton Lambert -norton-lambert 2338/tcp # Norton Lambert -# Richard de Mornay -3com-webview 2339/udp # 3Com WebView -3com-webview 2339/tcp # 3Com WebView -# Jennifer Grace -wrs_registry 2340/udp # WRS Registry -wrs_registry 2340/tcp # WRS Registry -# Christophe Cleraux -xiostatus 2341/udp # XIO Status -xiostatus 2341/tcp # XIO Status -# Randy Maas -manage-exec 2342/udp # Seagate Manage Exec -manage-exec 2342/tcp # Seagate Manage Exec -# Jim Flaherty -nati-logos 2343/udp # nati logos -nati-logos 2343/tcp # nati logos -# David Pierce -fcmsys 2344/udp # fcmsys -fcmsys 2344/tcp # fcmsys -dbm 2345/udp # dbm -dbm 2345/tcp # dbm -# Dean Robson -redstorm_join 2346/udp # Game Connection Port -redstorm_join 2346/tcp # Game Connection Port -redstorm_find 2347/udp # Game Announcement and Location -redstorm_find 2347/tcp # Game Announcement and Location -redstorm_info 2348/udp # Information to query for game status -redstorm_info 2348/tcp # Information to query for game status -redstorm_diag 2349/udp # Diagnostics Port -redstorm_diag 2349/tcp # Diagnostics Port -# David Weinstein -psbserver 2350/udp # psbserver -psbserver 2350/tcp # psbserver -psrserver 2351/udp # psrserver -psrserver 2351/tcp # psrserver -pslserver 2352/udp # pslserver -pslserver 2352/tcp # pslserver -pspserver 2353/udp # pspserver -pspserver 2353/tcp # pspserver -psprserver 2354/udp # psprserver -psprserver 2354/tcp # psprserver -psdbserver 2355/udp # psdbserver -psdbserver 2355/tcp # psdbserver -# Paul Reddy -gxtelmd 2356/udp # GXT License Managemant -gxtelmd 2356/tcp # GXT License Managemant -# Robert Hodgson -unihub-server 2357/udp # UniHub Server -unihub-server 2357/tcp # UniHub Server -# Tim Kenyon -futrix 2358/udp # Futrix -futrix 2358/tcp # Futrix -# Peter Frankenberg -flukeserver 2359/udp # FlukeServer -flukeserver 2359/tcp # FlukeServer -# Bill Marbaker -nexstorindltd 2360/udp # NexstorIndLtd -nexstorindltd 2360/tcp # NexstorIndLtd -# NexStor India Limited -tl1 2361/udp # TL1 -tl1 2361/tcp # TL1 -# Charles Scott Roberson -digiman 2362/udp # digiman -digiman 2362/tcp # digiman -# Aaron S. Kurland -mediacntrlnfsd 2363/udp # Media Central NFSD -mediacntrlnfsd 2363/tcp # Media Central NFSD -# shivakumar s. govindarajapuram -oi-2000 2364/udp # OI-2000 -oi-2000 2364/tcp # OI-2000 -# Software Horizons Inc. -dbref 2365/udp # dbref -dbref 2365/tcp # dbref -# Yoshihiro Yamazaki -qip-login 2366/udp # qip-login -qip-login 2366/tcp # qip-login -# Mike Morgan -service-ctrl 2367/udp # Service Control -service-ctrl 2367/tcp # Service Control -# Humberto Sanchez -opentable 2368/udp # OpenTable -opentable 2368/tcp # OpenTable -# Thomas Theobald -acs2000-dsp 2369/udp # ACS2000 DSP -acs2000-dsp 2369/tcp # ACS2000 DSP -# Jeffrey Beauchamp -l3-hbmon 2370/udp # L3-HBMon -l3-hbmon 2370/tcp # L3-HBMon -# Dolores Scott -#### Port 2370 Unofficially used by Compaq #### -worldwire 2371/udp # Compaq WorldWire Port -worldwire 2371/tcp # Compaq WorldWire Port -# Michael Spratte -# 2372-2380 Unassigned -compaq-https 2381/udp # Compaq HTTPS -compaq-https 2381/tcp # Compaq HTTPS -# Scott Shaffer -ms-olap3 2382/udp # Microsoft OLAP -ms-olap3 2382/tcp # Microsoft OLAP -ms-olap4 2383/udp # Microsoft OLAP -ms-olap4 2383/tcp # Microsoft OLAP -# Mosha Pasumansky -sd-capacity 2384/udp # SD-CAPACITY -sd-request 2384/tcp # SD-REQUEST -# Jason McManus -sd-data 2385/udp # SD-DATA -sd-data 2385/tcp # SD-DATA -# Jason McManus -virtualtape 2386/udp # Virtual Tape -virtualtape 2386/tcp # Virtual Tape -vsamredirector 2387/udp # VSAM Redirector -vsamredirector 2387/tcp # VSAM Redirector -# Ingo Franzki -mynahautostart 2388/udp # MYNAH AutoStart -mynahautostart 2388/tcp # MYNAH AutoStart -# Thomas J. Klehr -ovsessionmgr 2389/udp # OpenView Session Mgr -ovsessionmgr 2389/tcp # OpenView Session Mgr -# Eric Pulsipher -rsmtp 2390/udp # RSMTP -rsmtp 2390/tcp # RSMTP -# Geoff Collyer -3com-net-mgmt 2391/udp # 3COM Net Management -3com-net-mgmt 2391/tcp # 3COM Net Management -# Prathibha Nagvar -tacticalauth 2392/udp # Tactical Auth -tacticalauth 2392/tcp # Tactical Auth -# David Yon -ms-olap1 2393/udp # MS OLAP 1 -ms-olap1 2393/tcp # MS OLAP 1 -ms-olap2 2394/udp # MS OLAP 2 -ms-olap2 2394/tcp # MS OLAP 2 -# Mosha Pasumansky -lan900_remote 2395/udp # LAN900 Remote -lan900_remote 2395/tcp # LAN900 Remote -# Tom Quinlan -wusage 2396/udp # Wusage -wusage 2396/tcp # Wusage -# Thomas Boutell -ncl 2397/udp # NCL -ncl 2397/tcp # NCL -# Robert Wiebe -orbiter 2398/udp # Orbiter -orbiter 2398/tcp # Orbiter -# David Goldberg -fmpro-fdal 2399/udp # FileMaker, Inc. - Data Access Layer -fmpro-fdal 2399/tcp # FileMaker, Inc. - Data Access Layer -# Clay Maeckal -opequus-server 2400/udp # OpEquus Server -opequus-server 2400/tcp # OpEquus Server -# Gavin Hutchinson -cvspserver 2401/udp # cvspserver -cvspserver 2401/tcp # cvspserver -# Jim Kingdon -taskmaster2000 2402/udp # TaskMaster 2000 Server -taskmaster2000 2402/tcp # TaskMaster 2000 Server -taskmaster2000 2403/udp # TaskMaster 2000 Web -taskmaster2000 2403/tcp # TaskMaster 2000 Web -# Ed Odjaghian -iec-104 2404/udp # IEC 60870-5-104 process control over IP -iec-104 2404/tcp # IEC 60870-5-104 process control over IP -# Walter K. Eichelburg -trc-netpoll 2405/udp # TRC Netpoll -trc-netpoll 2405/tcp # TRC Netpoll -# Bizhan Ghavami -jediserver 2406/udp # JediServer -jediserver 2406/tcp # JediServer -# Paul McEntire -orion 2407/udp # Orion -orion 2407/tcp # Orion -# Matthew Horoschun -optimanet 2408/udp # OptimaNet -optimanet 2408/tcp # OptimaNet -# John Graham-Cumming -sns-protocol 2409/udp # SNS Protocol -sns-protocol 2409/tcp # SNS Protocol -# Amir Blich -vrts-registry 2410/udp # VRTS Registry -vrts-registry 2410/tcp # VRTS Registry -# Pranay Varma -netwave-ap-mgmt 2411/udp # Netwave AP Management -netwave-ap-mgmt 2411/tcp # Netwave AP Management -# Johnny Zweig -cdn 2412/udp # CDN -cdn 2412/tcp # CDN -# Alan Noble -orion-rmi-reg 2413/udp # orion-rmi-reg -orion-rmi-reg 2413/tcp # orion-rmi-reg -# J.S. Greenfield -beeyond 2414/udp # Beeyond -beeyond 2414/tcp # Beeyond -# Bob Deblier -codima-rtp 2415/udp # Codima Remote Transaction Protocol -codima-rtp 2415/tcp # Codima Remote Transaction Protocol -# Sylvia Ross -rmtserver 2416/udp # RMT Server -rmtserver 2416/tcp # RMT Server -# Yvon Marineau -composit-server 2417/udp # Composit Server -composit-server 2417/tcp # Composit Server -# Katsuaki Naoi -cas 2418/udp # cas -cas 2418/tcp # cas -# Akiyoshi Ochi -attachmate-s2s 2419/udp # Attachmate S2S -attachmate-s2s 2419/tcp # Attachmate S2S -# Chris Rominski -dslremote-mgmt 2420/udp # DSL Remote Management -dslremote-mgmt 2420/tcp # DSL Remote Management -# Westell, Inc. -g-talk 2421/udp # G-Talk -g-talk 2421/tcp # G-Talk -# Matt Hammond -crmsbits 2422/udp # CRMSBITS -crmsbits 2422/tcp # CRMSBITS -# Rod Ward -rnrp 2423/udp # RNRP -rnrp 2423/tcp # RNRP -# Per Sahlqvist -kofax-svr 2424/udp # KOFAX-SVR -kofax-svr 2424/tcp # KOFAX-SVR -# Terry Reagan -fjitsuappmgr 2425/udp # Fujitsu App Manager -fjitsuappmgr 2425/tcp # Fujitsu App Manager -# Hiroyuki Kawabuchi -# 2426 Unassigned (Removed 2002-04-29) -mgcp-gateway 2427/udp # Media Gateway Control Protocol Gateway -mgcp-gateway 2427/tcp # Media Gateway Control Protocol Gateway -# Christian Huitema -ott 2428/udp # One Way Trip Time -ott 2428/tcp # One Way Trip Time -# Greg Troxel -ft-role 2429/udp # FT-ROLE -ft-role 2429/tcp # FT-ROLE -# Doug Boone -venus 2430/udp # venus -venus 2430/tcp # venus -venus-se 2431/udp # venus-se -venus-se 2431/tcp # venus-se -codasrv 2432/udp # codasrv -codasrv 2432/tcp # codasrv -codasrv-se 2433/udp # codasrv-se -codasrv-se 2433/tcp # codasrv-se -# Robert Watson -pxc-epmap 2434/udp # pxc-epmap -pxc-epmap 2434/tcp # pxc-epmap -# Jun Nakamura -optilogic 2435/udp # OptiLogic -optilogic 2435/tcp # OptiLogic -# Clark Williams -topx 2436/udp # TOP/X -topx 2436/tcp # TOP/X -# Dragos Pop -unicontrol 2437/udp # UniControl -unicontrol 2437/tcp # UniControl -# Ing. Markus Huemer -msp 2438/udp # MSP -msp 2438/tcp # MSP -# Evan Caves -sybasedbsynch 2439/udp # SybaseDBSynch -sybasedbsynch 2439/tcp # SybaseDBSynch -# Dave Neudoerffer -spearway 2440/udp # Spearway Lockers -spearway 2440/tcp # Spearway Lockers -# Pierre Frisch -pvsw-inet 2441/udp # Pervasive I*net Data Server -pvsw-inet 2441/tcp # Pervasive I*net Data Server -# Chuck Talk -netangel 2442/udp # Netangel -netangel 2442/tcp # Netangel -# Ladislav Baranyay -powerclientcsf 2443/udp # PowerClient Central Storage Facility -powerclientcsf 2443/tcp # PowerClient Central Storage Facility -# Brian Klassen -btpp2sectrans 2444/udp # BT PP2 Sectrans -btpp2sectrans 2444/tcp # BT PP2 Sectrans -# Ian Daniels -dtn1 2445/udp # DTN1 -dtn1 2445/tcp # DTN1 -# Bob Gaddie -bues_service 2446/udp # bues_service -bues_service 2446/tcp # bues_service -# Leonhard Diekmann -# -ovwdb 2447/udp # OpenView NNM daemon -ovwdb 2447/tcp # OpenView NNM daemon -# Eric Pulsipher -hpppssvr 2448/udp # hpppsvr -hpppssvr 2448/tcp # hpppsvr -# Bridgette Landers -ratl 2449/udp # RATL -ratl 2449/tcp # RATL -# Paul Greenfield -netadmin 2450/udp # netadmin -netadmin 2450/tcp # netadmin -netchat 2451/udp # netchat -netchat 2451/tcp # netchat -# Julian Mehnle -snifferclient 2452/udp # SnifferClient -snifferclient 2452/tcp # SnifferClient -# Amy Weaver -madge-om 2453/udp # madge-om -madge-om 2453/tcp # madge-om -# Andrew Draper -indx-dds 2454/udp # IndX-DDS -indx-dds 2454/tcp # IndX-DDS -# Paul Carmichael -wago-io-system 2455/udp # WAGO-IO-SYSTEM -wago-io-system 2455/tcp # WAGO-IO-SYSTEM -# Uwe Rathert -altav-remmgt 2456/udp # altav-remmgt -altav-remmgt 2456/tcp # altav-remmgt -# Gary M. Allen -rapido-ip 2457/udp # Rapido_IP -rapido-ip 2457/tcp # Rapido_IP -# Man Shuen Cheung -griffin 2458/udp # griffin -griffin 2458/tcp # griffin -# Tom Taylor -community 2459/udp # Community -community 2459/tcp # Community -# David Schwartz -ms-theater 2460/udp # ms-theater -ms-theater 2460/tcp # ms-theater -# Anton Kucer -qadmifoper 2461/udp # qadmifoper -qadmifoper 2461/tcp # qadmifoper -qadmifevent 2462/udp # qadmifevent -qadmifevent 2462/tcp # qadmifevent -# Pekka Takaranta -symbios-raid 2463/udp # Symbios Raid -symbios-raid 2463/tcp # Symbios Raid -# Bill Delaney -direcpc-si 2464/udp # DirecPC SI -direcpc-si 2464/tcp # DirecPC SI -# Doug Dillon -lbm 2465/udp # Load Balance Management -lbm 2465/tcp # Load Balance Management -lbf 2466/udp # Load Balance Forwarding -lbf 2466/tcp # Load Balance Forwarding -# Kazuhiro Koide -high-criteria 2467/udp # High Criteria -high-criteria 2467/tcp # High Criteria -# Konstantin Iavid -qip-msgd 2468/udp # qip_msgd -qip-msgd 2468/tcp # qip_msgd -# Mike Morgan -mti-tcs-comm 2469/udp # MTI-TCS-COMM -mti-tcs-comm 2469/tcp # MTI-TCS-COMM -# Mario Bonin -taskman-port 2470/udp # taskman port -taskman-port 2470/tcp # taskman port -# Boris Panteleev -seaodbc 2471/udp # SeaODBC -seaodbc 2471/tcp # SeaODBC -# Adrian Hornby -c3 2472/udp # C3 -c3 2472/tcp # C3 -# Eckhard Grieger -aker-cdp 2473/udp # Aker-cdp -aker-cdp 2473/tcp # Aker-cdp -# Rodrigo Ormonde -vitalanalysis 2474/udp # Vital Analysis -vitalanalysis 2474/tcp # Vital Analysis -# Srinivas Reddy -ace-server 2475/udp # ACE Server -ace-server 2475/tcp # ACE Server -ace-svr-prop 2476/udp # ACE Server Propagation -ace-svr-prop 2476/tcp # ACE Server Propagation -ssm-cvs 2477/udp # SecurSight Certificate Valifation Service -ssm-cvs 2477/tcp # SecurSight Certificate Valifation Service -ssm-cssps 2478/udp # SecurSight Authentication Server (SSL) -ssm-cssps 2478/tcp # SecurSight Authentication Server (SSL) -ssm-els 2479/udp # SecurSight Event Logging Server (SSL) -ssm-els 2479/tcp # SecurSight Event Logging Server (SSL) -# John Linn -lingwood 2480/udp # Lingwood's Detail -lingwood 2480/tcp # Lingwood's Detail -# Dave Richmond -giop 2481/udp # Oracle GIOP -giop 2481/tcp # Oracle GIOP -giop-ssl 2482/udp # Oracle GIOP SSL -giop-ssl 2482/tcp # Oracle GIOP SSL -ttc 2483/udp # Oracle TTC -ttc 2483/tcp # Oracle TTC -ttc-ssl 2484/udp # Oracle TTC SSL -ttc-ssl 2484/tcp # Oracle TTC SSL -# Chandar Venkataraman -netobjects1 2485/udp # Net Objects1 -netobjects1 2485/tcp # Net Objects1 -netobjects2 2486/udp # Net Objects2 -netobjects2 2486/tcp # Net Objects2 -# Francois Granade -pns 2487/udp # Policy Notice Service -pns 2487/tcp # Policy Notice Service -# Akiyoshi Ochi -moy-corp 2488/udp # Moy Corporation -moy-corp 2488/tcp # Moy Corporation -# Gang Gong Moy -tsilb 2489/udp # TSILB -tsilb 2489/tcp # TSILB -# James Irwin -qip-qdhcp 2490/udp # qip_qdhcp -qip-qdhcp 2490/tcp # qip_qdhcp -# Mike Morgan -conclave-cpp 2491/udp # Conclave CPP -conclave-cpp 2491/tcp # Conclave CPP -# Larry Lipstone -groove 2492/udp # GROOVE -groove 2492/tcp # GROOVE -# Ray Ozzie -talarian-mqs 2493/udp # Talarian MQS -talarian-mqs 2493/tcp # Talarian MQS -# Jim Stabile -bmc-ar 2494/udp # BMC AR -bmc-ar 2494/tcp # BMC AR -# Shelia Childs -fast-rem-serv 2495/udp # Fast Remote Services -fast-rem-serv 2495/tcp # Fast Remote Services -# Scott St. Clair -dirgis 2496/udp # DIRGIS -dirgis 2496/tcp # DIRGIS -# Deutschland Informations- und -# Reservierungsgesellschaft mbH -quaddb 2497/udp # Quad DB -quaddb 2497/tcp # Quad DB -# Jeff Rosenthal -odn-castraq 2498/udp # ODN-CasTraq -odn-castraq 2498/tcp # ODN-CasTraq -# Richard Hodges -unicontrol 2499/udp # UniControl -unicontrol 2499/tcp # UniControl -# Ing. Markus Huemer -rtsserv 2500/udp # Resource Tracking system server -rtsserv 2500/tcp # Resource Tracking system server -rtsclient 2501/udp # Resource Tracking system client -rtsclient 2501/tcp # Resource Tracking system client -# Aubrey Turner -# -kentrox-prot 2502/udp # Kentrox Protocol -kentrox-prot 2502/tcp # Kentrox Protocol -# Anil Lakhwara -nms-dpnss 2503/udp # NMS-DPNSS -nms-dpnss 2503/tcp # NMS-DPNSS -# Jean-Christophe Desire -# -wlbs 2504/udp # WLBS -wlbs 2504/tcp # WLBS -# William Bain -# 2505 Removed (2002-06-14) -jbroker 2506/udp # jbroker -jbroker 2506/tcp # jbroker -# Rohit Garg -spock 2507/udp # spock -spock 2507/tcp # spock -# Jon A. Christopher -jdatastore 2508/udp # JDataStore -jdatastore 2508/tcp # JDataStore -# Tod Landis -fjmpss 2509/udp # fjmpss -fjmpss 2509/tcp # fjmpss -# Makoto Watanabe -fjappmgrbulk 2510/udp # fjappmgrbulk -fjappmgrbulk 2510/tcp # fjappmgrbulk -# Hiroyuki Kawabuchi -metastorm 2511/udp # Metastorm -metastorm 2511/tcp # Metastorm -# Eric Isom -citrixima 2512/udp # Citrix IMA -citrixima 2512/tcp # Citrix IMA -citrixadmin 2513/udp # Citrix ADMIN -citrixadmin 2513/tcp # Citrix ADMIN -# Myk Willis -facsys-ntp 2514/udp # Facsys NTP -facsys-ntp 2514/tcp # Facsys NTP -facsys-router 2515/udp # Facsys Router -facsys-router 2515/tcp # Facsys Router -# Jeff Hoffman -maincontrol 2516/udp # Main Control -maincontrol 2516/tcp # Main Control -# Nathan Sadia -call-sig-trans 2517/udp # H.323 Annex E call signaling transport -call-sig-trans 2517/tcp # H.323 Annex E call signaling transport -# Gur Kimchi -willy 2518/udp # Willy -willy 2518/tcp # Willy -# Carl-Johan Wik -globmsgsvc 2519/udp # globmsgsvc -globmsgsvc 2519/tcp # globmsgsvc -# David Wiltz -pvsw 2520/udp # Pervasive Listener -pvsw 2520/tcp # Pervasive Listener -# Chuck Talk -adaptecmgr 2521/udp # Adaptec Manager -adaptecmgr 2521/tcp # Adaptec Manager -# Mark Parenti -windb 2522/udp # WinDb -windb 2522/tcp # WinDb -# Larry Traylor -qke-llc-v3 2523/udp # Qke LLC V.3 -qke-llc-v3 2523/tcp # Qke LLC V.3 -# Joerg Niehoff -optiwave-lm 2524/udp # Optiwave License Management -optiwave-lm 2524/tcp # Optiwave License Management -# Slawomir Krzesinski -ms-v-worlds 2525/udp # MS V-Worlds -ms-v-worlds 2525/tcp # MS V-Worlds -# Pete Wong -ema-sent-lm 2526/udp # EMA License Manager -ema-sent-lm 2526/tcp # EMA License Manager -# Thaddeus Perala -iqserver 2527/udp # IQ Server -iqserver 2527/tcp # IQ Server -# Nick Straguzzi -ncr_ccl 2528/udp # NCR CCL -ncr_ccl 2528/tcp # NCR CCL -# Amitava Dutta -utsftp 2529/udp # UTS FTP -utsftp 2529/tcp # UTS FTP -# David Moore -vrcommerce 2530/udp # VR Commerce -vrcommerce 2530/tcp # VR Commerce -# Yosi Mass -ito-e-gui 2531/udp # ITO-E GUI -ito-e-gui 2531/tcp # ITO-E GUI -# Michael Haeuptle -ovtopmd 2532/udp # OVTOPMD -ovtopmd 2532/tcp # OVTOPMD -# Eric Pulsipher -snifferserver 2533/udp # SnifferServer -snifferserver 2533/tcp # SnifferServer -# Amy Weaver -combox-web-acc 2534/udp # Combox Web Access -combox-web-acc 2534/tcp # Combox Web Access -# Yochai Cohen -madcap 2535/udp # MADCAP -madcap 2535/tcp # MADCAP -# Stephen Hanna -btpp2audctr1 2536/udp # btpp2audctr1 -btpp2audctr1 2536/tcp # btpp2audctr1 -# Ian Daniels -upgrade 2537/udp # Upgrade Protocol -upgrade 2537/tcp # Upgrade Protocol -# Breck Auten -vnwk-prapi 2538/udp # vnwk-prapi -vnwk-prapi 2538/tcp # vnwk-prapi -# John Hasselkus -vsiadmin 2539/udp # VSI Admin -vsiadmin 2539/tcp # VSI Admin -# Rob Juergens -lonworks 2540/udp # LonWorks -lonworks 2540/tcp # LonWorks -lonworks2 2541/udp # LonWorks2 -lonworks2 2541/tcp # LonWorks2 -# Gary Bartlett -davinci 2542/udp # daVinci Presenter -davinci 2542/tcp # daVinci Presenter -# b-novative GmbH -reftek 2543/udp # REFTEK -reftek 2543/tcp # REFTEK -# Robert Banfill -novell-zen 2544/udp # Novell ZEN -novell-zen 2544/tcp # Novell ZEN -# Randy Cook -sis-emt 2545/udp # sis-emt -sis-emt 2545/tcp # sis-emt -# Bill Crawford -vytalvaultbrtp 2546/udp # vytalvaultbrtp -vytalvaultbrtp 2546/tcp # vytalvaultbrtp -vytalvaultvsmp 2547/udp # vytalvaultvsmp -vytalvaultvsmp 2547/tcp # vytalvaultvsmp -vytalvaultpipe 2548/udp # vytalvaultpipe -vytalvaultpipe 2548/tcp # vytalvaultpipe -# Tim Boldt -ipass 2549/udp # IPASS -ipass 2549/tcp # IPASS -# Michael Fischer -ads 2550/udp # ADS -ads 2550/tcp # ADS -# Michael O'Connor -isg-uda-server 2551/udp # ISG UDA Server -isg-uda-server 2551/tcp # ISG UDA Server -# Dror Harari -call-logging 2552/udp # Call Logging -call-logging 2552/tcp # Call Logging -# Dean Webb -efidiningport 2553/udp # efidiningport -efidiningport 2553/tcp # efidiningport -# Lynn Carter -vcnet-link-v10 2554/udp # VCnet-Link v10 -vcnet-link-v10 2554/tcp # VCnet-Link v10 -# Csaba Mate -compaq-wcp 2555/udp # Compaq WCP -compaq-wcp 2555/tcp # Compaq WCP -# Ferruccio Barletta -nicetec-nmsvc 2556/udp # nicetec-nmsvc -nicetec-nmsvc 2556/tcp # nicetec-nmsvc -nicetec-mgmt 2557/udp # nicetec-mgmt -nicetec-mgmt 2557/tcp # nicetec-mgmt -# Joerg Paulus -pclemultimedia 2558/udp # PCLE Multi Media -pclemultimedia 2558/tcp # PCLE Multi Media -# Bernd Scharping -lstp 2559/udp # LSTP -lstp 2559/tcp # LSTP -# Waiki Wright -labrat 2560/udp # labrat -labrat 2560/tcp # labrat -# John Harvey -mosaixcc 2561/udp # MosaixCC -mosaixcc 2561/tcp # MosaixCC -# Steven Frare -delibo 2562/udp # Delibo -delibo 2562/tcp # Delibo -# NovaWiz LTD -cti-redwood 2563/udp # CTI Redwood -cti-redwood 2563/tcp # CTI Redwood -# Songwon Chi -hp-3000-telnet 2564/tcp # HP 3000 NS/VT block mode telnet -# -coord-svr 2565/udp # Coordinator Server -coord-svr 2565/tcp # Coordinator Server -# Richard Steiger -pcs-pcw 2566/udp # pcs-pcw -pcs-pcw 2566/tcp # pcs-pcw -# W. Jordan Fitzhugh -clp 2567/udp # Cisco Line Protocol -clp 2567/tcp # Cisco Line Protocol -# Susan Hinrichs -spamtrap 2568/udp # SPAM TRAP -spamtrap 2568/tcp # SPAM TRAP -# Chuck Bennett -sonuscallsig 2569/udp # Sonus Call Signal -sonuscallsig 2569/tcp # Sonus Call Signal -# Mark Garti -hs-port 2570/udp # HS Port -hs-port 2570/tcp # HS Port -# Uri Doron -cecsvc 2571/udp # CECSVC -cecsvc 2571/tcp # CECSVC -# Roger Pao -ibp 2572/udp # IBP -ibp 2572/tcp # IBP -# Jonathan Downes -trustestablish 2573/udp # Trust Establish -trustestablish 2573/tcp # Trust Establish -# Yosi Mass -blockade-bpsp 2574/udp # Blockade BPSP -blockade-bpsp 2574/tcp # Blockade BPSP -# VP - Research & Development -hl7 2575/udp # HL7 -hl7 2575/tcp # HL7 -# Tim Jacobs -tclprodebugger 2576/udp # TCL Pro Debugger -tclprodebugger 2576/tcp # TCL Pro Debugger -scipticslsrvr 2577/udp # Scriptics Lsrvr -scipticslsrvr 2577/tcp # Scriptics Lsrvr -# Brent Welch -rvs-isdn-dcp 2578/udp # RVS ISDN DCP -rvs-isdn-dcp 2578/tcp # RVS ISDN DCP -# Michael Zirpel -mpfoncl 2579/udp # mpfoncl -mpfoncl 2579/tcp # mpfoncl -# Itaru Kimura -tributary 2580/udp # Tributary -tributary 2580/tcp # Tributary -# Louis Lu -argis-te 2581/udp # ARGIS TE -argis-te 2581/tcp # ARGIS TE -argis-ds 2582/udp # ARGIS DS -argis-ds 2582/tcp # ARGIS DS -# John Legh-Page -mon 2583/udp # MON -mon 2583/tcp # MON -# Jim Trocki -cyaserv 2584/udp # cyaserv -cyaserv 2584/tcp # cyaserv -# Morgan Jones -netx-server 2585/udp # NETX Server -netx-server 2585/tcp # NETX Server -netx-agent 2586/udp # NETX Agent -netx-agent 2586/tcp # NETX Agent -# Brett Dolecheck -masc 2587/udp # MASC -masc 2587/tcp # MASC -# Pavlin Ivanov Radoslavov -# -privilege 2588/udp # Privilege -privilege 2588/tcp # Privilege -# Gil Hecht -quartus-tcl 2589/udp # quartus tcl -quartus-tcl 2589/tcp # quartus tcl -# Subroto Datta -idotdist 2590/udp # idotdist -idotdist 2590/tcp # idotdist -# Jason Hunter -maytagshuffle 2591/udp # Maytag Shuffle -maytagshuffle 2591/tcp # Maytag Shuffle -# Maytag Corporation -netrek 2592/udp # netrek -netrek 2592/tcp # netrek -# Al Guetzlaff -mns-mail 2593/udp # MNS Mail Notice Service -mns-mail 2593/tcp # MNS Mail Notice Service -# Rumiko Kikuta -dts 2594/udp # Data Base Server -dts 2594/tcp # Data Base Server -# Andreas Roene -worldfusion1 2595/udp # World Fusion 1 -worldfusion1 2595/tcp # World Fusion 1 -worldfusion2 2596/udp # World Fusion 2 -worldfusion2 2596/tcp # World Fusion 2 -# World Fusion -homesteadglory 2597/udp # Homestead Glory -homesteadglory 2597/tcp # Homestead Glory -# John Tokash -citriximaclient 2598/udp # Citrix MA Client -citriximaclient 2598/tcp # Citrix MA Client -# Myk Willis -snapd 2599/udp # Snap Discovery -snapd 2599/tcp # Snap Discovery -# Kevin Osborn -hpstgmgr 2600/udp # HPSTGMGR -hpstgmgr 2600/tcp # HPSTGMGR -# Kevin Collins -discp-client 2601/udp # discp client -discp-client 2601/tcp # discp client -discp-server 2602/udp # discp server -discp-server 2602/tcp # discp server -# Peter White -servicemeter 2603/udp # Service Meter -servicemeter 2603/tcp # Service Meter -# Duncan Hare -nsc-ccs 2604/udp # NSC CCS -nsc-ccs 2604/tcp # NSC CCS -nsc-posa 2605/udp # NSC POSA -nsc-posa 2605/tcp # NSC POSA -# Tom Findley -netmon 2606/udp # Dell Netmon -netmon 2606/tcp # Dell Netmon -connection 2607/udp # Dell Connection -connection 2607/tcp # Dell Connection -# Sudhir Shetty -wag-service 2608/udp # Wag Service -wag-service 2608/tcp # Wag Service -# Gilles Bourquard -system-monitor 2609/udp # System Monitor -system-monitor 2609/tcp # System Monitor -# Greg Robson-Garth -versa-tek 2610/udp # VersaTek -versa-tek 2610/tcp # VersaTek -# James Kou -lionhead 2611/udp # LIONHEAD -lionhead 2611/tcp # LIONHEAD -# Tim Rance -qpasa-agent 2612/udp # Qpasa Agent -qpasa-agent 2612/tcp # Qpasa Agent -# Craig Ching -smntubootstrap 2613/udp # SMNTUBootstrap -smntubootstrap 2613/tcp # SMNTUBootstrap -# Matt Cecile -neveroffline 2614/udp # Never Offline -neveroffline 2614/tcp # Never Offline -# Dustin Brand -firepower 2615/udp # firepower -firepower 2615/tcp # firepower -# Jason Volk -appswitch-emp 2616/udp # appswitch-emp -appswitch-emp 2616/tcp # appswitch-emp -# Ted Ross -cmadmin 2617/udp # Clinical Context Managers -cmadmin 2617/tcp # Clinical Context Managers -# Mark Morwood -priority-e-com 2618/udp # Priority E-Com -priority-e-com 2618/tcp # Priority E-Com -# Marcelo Einhorn -bruce 2619/udp # bruce -bruce 2619/tcp # bruce -# Alec Muffett -lpsrecommender 2620/udp # LPSRecommender -lpsrecommender 2620/tcp # LPSRecommender -# Pritham Shetty -miles-apart 2621/udp # Miles Apart Jukebox Server -miles-apart 2621/tcp # Miles Apart Jukebox Server -# Michael Rathmann -metricadbc 2622/udp # MetricaDBC -metricadbc 2622/tcp # MetricaDBC -# Russ Olivant -lmdp 2623/udp # LMDP -lmdp 2623/tcp # LMDP -# Ken Bailey -aria 2624/udp # Aria -aria 2624/tcp # Aria -# Logan Bruns -blwnkl-port 2625/udp # Blwnkl Port -blwnkl-port 2625/tcp # Blwnkl Port -# Weng Chin (Winson) Yung -gbjd816 2626/udp # gbjd816 -gbjd816 2626/tcp # gbjd816 -# George Balesta -moshebeeri 2627/udp # Moshe Beeri -moshebeeri 2627/tcp # Moshe Beeri -# Moshe Beeri -dict 2628/udp # DICT -dict 2628/tcp # DICT -# Rik Faith -sitaraserver 2629/udp # Sitara Server -sitaraserver 2629/tcp # Sitara Server -sitaramgmt 2630/udp # Sitara Management -sitaramgmt 2630/tcp # Sitara Management -sitaradir 2631/udp # Sitara Dir -sitaradir 2631/tcp # Sitara Dir -# Manickam R.Sridhar -irdg-post 2632/udp # IRdg Post -irdg-post 2632/tcp # IRdg Post -# IRdg, Inc. -interintelli 2633/udp # InterIntelli -interintelli 2633/tcp # InterIntelli -# Mike Gagle -pk-electronics 2634/udp # PK Electronics -pk-electronics 2634/tcp # PK Electronics -# Seb Ibis -backburner 2635/udp # Back Burner -backburner 2635/tcp # Back Burner -# Kevin Teiskoetter -solve 2636/udp # Solve -solve 2636/tcp # Solve -# Peter Morrison -imdocsvc 2637/udp # Import Document Service -imdocsvc 2637/tcp # Import Document Service -# Zia Bhatti -sybaseanywhere 2638/udp # Sybase Anywhere -sybaseanywhere 2638/tcp # Sybase Anywhere -# Dave Neudoerffer -aminet 2639/udp # AMInet -aminet 2639/tcp # AMInet -# Alcorn McBride Inc. -sai_sentlm 2640/udp # Sabbagh Associates Licence Manager -sai_sentlm 2640/tcp # Sabbagh Associates Licence Manager -# Elias Sabbagh -hdl-srv 2641/udp # HDL Server -hdl-srv 2641/tcp # HDL Server -# David Ely -tragic 2642/udp # Tragic -tragic 2642/tcp # Tragic -# Stu Mark -gte-samp 2643/udp # GTE-SAMP -gte-samp 2643/tcp # GTE-SAMP -# Asher Altman -travsoft-ipx-t 2644/udp # Travsoft IPX Tunnel -travsoft-ipx-t 2644/tcp # Travsoft IPX Tunnel -# Jack Wilson -novell-ipx-cmd 2645/udp # Novell IPX CMD -novell-ipx-cmd 2645/tcp # Novell IPX CMD -# Juan Carlos Luciani -and-lm 2646/udp # AND License Manager -and-lm 2646/tcp # AND License Manager -# Dick van der Sijs -syncserver 2647/udp # SyncServer -syncserver 2647/tcp # SyncServer -# Dave Finnegan -upsnotifyprot 2648/udp # Upsnotifyprot -upsnotifyprot 2648/tcp # Upsnotifyprot -# Mario Leboute -vpsipport 2649/udp # VPSIPPORT -vpsipport 2649/tcp # VPSIPPORT -# Joon Radley -eristwoguns 2650/udp # eristwoguns -eristwoguns 2650/tcp # eristwoguns -# NetPro Computing Inc. -ebinsite 2651/udp # EBInSite -ebinsite 2651/tcp # EBInSite -# Lefteris Kalamaras -interpathpanel 2652/udp # InterPathPanel -interpathpanel 2652/tcp # InterPathPanel -# Stephen Misel -sonus 2653/udp # Sonus -sonus 2653/tcp # Sonus -# Mark Garti -corel_vncadmin 2654/udp # Corel VNC Admin -corel_vncadmin 2654/tcp # Corel VNC Admin -# Oleg Noskov -unglue 2655/udp # UNIX Nt Glue -unglue 2655/tcp # UNIX Nt Glue -# Peter Santoro -kana 2656/udp # Kana -kana 2656/tcp # Kana -# Colin Goldstein -sns-dispatcher 2657/udp # SNS Dispatcher -sns-dispatcher 2657/tcp # SNS Dispatcher -sns-admin 2658/udp # SNS Admin -sns-admin 2658/tcp # SNS Admin -sns-query 2659/udp # SNS Query -sns-query 2659/tcp # SNS Query -# Mary Holstege -gcmonitor 2660/udp # GC Monitor -gcmonitor 2660/tcp # GC Monitor -# Gustavo Rodriguez-Rivera -olhost 2661/udp # OLHOST -olhost 2661/tcp # OLHOST -# Robert Ripberger -bintec-capi 2662/udp # BinTec-CAPI -bintec-capi 2662/tcp # BinTec-CAPI -bintec-tapi 2663/udp # BinTec-TAPI -bintec-tapi 2663/tcp # BinTec-TAPI -# -patrol-mq-gm 2664/udp # Patrol for MQ GM -patrol-mq-gm 2664/tcp # Patrol for MQ GM -patrol-mq-nm 2665/udp # Patrol for MQ NM -patrol-mq-nm 2665/tcp # Patrol for MQ NM -# Richard Nikula -extensis 2666/udp # extensis -extensis 2666/tcp # extensis -# Milton Sagen -alarm-clock-s 2667/udp # Alarm Clock Server -alarm-clock-s 2667/tcp # Alarm Clock Server -alarm-clock-c 2668/udp # Alarm Clock Client -alarm-clock-c 2668/tcp # Alarm Clock Client -toad 2669/udp # TOAD -toad 2669/tcp # TOAD -# Michael Marking -tve-announce 2670/udp # TVE Announce -tve-announce 2670/tcp # TVE Announce -# Dean Blackketter -newlixreg 2671/udp # newlixreg -newlixreg 2671/tcp # newlixreg -# Jean-Serge Gagnon -nhserver 2672/udp # nhserver -nhserver 2672/tcp # nhserver -# Adrian Hornby -firstcall42 2673/udp # First Call 42 -firstcall42 2673/tcp # First Call 42 -# Luke Bowen -ewnn 2674/udp # ewnn -ewnn 2674/tcp # ewnn -# Yasunari Yamashita -ttc-etap 2675/udp # TTC ETAP -ttc-etap 2675/tcp # TTC ETAP -# Daniel Becker -simslink 2676/udp # SIMSLink -simslink 2676/tcp # SIMSLink -# Steve Ryckman -gadgetgate1way 2677/udp # Gadget Gate 1 Way -gadgetgate1way 2677/tcp # Gadget Gate 1 Way -gadgetgate2way 2678/udp # Gadget Gate 2 Way -gadgetgate2way 2678/tcp # Gadget Gate 2 Way -# Matt Rollins -syncserverssl 2679/udp # Sync Server SSL -syncserverssl 2679/tcp # Sync Server SSL -# Dave Finnegan -pxc-sapxom 2680/udp # pxc-sapxom -pxc-sapxom 2680/tcp # pxc-sapxom -# Hideki Kiriyama -mpnjsomb 2681/udp # mpnjsomb -mpnjsomb 2681/tcp # mpnjsomb -# Takenori Miyahara -# 2682 Removed (2002-04-30) -ncdloadbalance 2683/udp # NCDLoadBalance -ncdloadbalance 2683/tcp # NCDLoadBalance -# Tim Stevenson -mpnjsosv 2684/udp # mpnjsosv -mpnjsosv 2684/tcp # mpnjsosv -mpnjsocl 2685/udp # mpnjsocl -mpnjsocl 2685/tcp # mpnjsocl -mpnjsomg 2686/udp # mpnjsomg -mpnjsomg 2686/tcp # mpnjsomg -# Takenori Miyahara -pq-lic-mgmt 2687/udp # pq-lic-mgmt -pq-lic-mgmt 2687/tcp # pq-lic-mgmt -# Bob Sledge -md-cg-http 2688/udp # md-cf-http -md-cg-http 2688/tcp # md-cf-http -# Lyndon Nerenberg -fastlynx 2689/udp # FastLynx -fastlynx 2689/tcp # FastLynx -# Dave Sewell -hp-nnm-data 2690/udp # HP NNM Embedded Database -hp-nnm-data 2690/tcp # HP NNM Embedded Database -# Chris Das -itinternet 2691/udp # ITInternet ISM Server -itinternet 2691/tcp # ITInternet ISM Server -# Ron Ehli -admins-lms 2692/udp # Admins LMS -admins-lms 2692/tcp # Admins LMS -# Dagfinn Saether -belarc-http 2693/udp # belarc-http -belarc-http 2693/tcp # belarc-http -# Gary Newman -pwrsevent 2694/udp # pwrsevent -pwrsevent 2694/tcp # pwrsevent -# Yoshinobu Nakamura -# -vspread 2695/udp # VSPREAD -vspread 2695/tcp # VSPREAD -# Sumitake kobayashi -# -unifyadmin 2696/udp # Unify Admin -unifyadmin 2696/tcp # Unify Admin -# Duane Gibson -oce-snmp-trap 2697/udp # Oce SNMP Trap Port -oce-snmp-trap 2697/tcp # Oce SNMP Trap Port -# Peter Teeuwen -mck-ivpip 2698/udp # MCK-IVPIP -mck-ivpip 2698/tcp # MCK-IVPIP -# Robert Vincent -csoft-plusclnt 2699/udp # Csoft Plus Client -csoft-plusclnt 2699/tcp # Csoft Plus Client -# Nedelcho Stanev -tqdata 2700/udp # tqdata -tqdata 2700/tcp # tqdata -# Al Guetzlaff -sms-rcinfo 2701/udp # SMS RCINFO -sms-rcinfo 2701/tcp # SMS RCINFO -sms-xfer 2702/udp # SMS XFER -sms-xfer 2702/tcp # SMS XFER -sms-chat 2703/udp # SMS CHAT -sms-chat 2703/tcp # SMS CHAT -sms-remctrl 2704/udp # SMS REMCTRL -sms-remctrl 2704/tcp # SMS REMCTRL -# Tom Friend -sds-admin 2705/udp # SDS Admin -sds-admin 2705/tcp # SDS Admin -# Don Traub -ncdmirroring 2706/udp # NCD Mirroring -ncdmirroring 2706/tcp # NCD Mirroring -# Tim Stevenson -emcsymapiport 2707/udp # EMCSYMAPIPORT -emcsymapiport 2707/tcp # EMCSYMAPIPORT -# Bruce Ferjulian -banyan-net 2708/udp # Banyan-Net -banyan-net 2708/tcp # Banyan-Net -# R. Thirumurthy -supermon 2709/udp # Supermon -supermon 2709/tcp # Supermon -# Ron Minnich -sso-service 2710/udp # SSO Service -sso-service 2710/tcp # SSO Service -sso-control 2711/udp # SSO Control -sso-control 2711/tcp # SSO Control -# Martin Proulx -aocp 2712/udp # Axapta Object Communication Protocol -aocp 2712/tcp # Axapta Object Communication Protocol -# Jakob Steen Hansen -raven1 2713/udp # Raven1 -raven1 2713/tcp # Raven1 -raven2 2714/udp # Raven2 -raven2 2714/tcp # Raven2 -# Daniel Sorlov -hpstgmgr2 2715/udp # HPSTGMGR2 -hpstgmgr2 2715/tcp # HPSTGMGR2 -# Kevin Collins -inova-ip-disco 2716/udp # Inova IP Disco -inova-ip-disco 2716/tcp # Inova IP Disco -# Chris Koeritz -pn-requester 2717/udp # PN REQUESTER -pn-requester 2717/tcp # PN REQUESTER -pn-requester2 2718/udp # PN REQUESTER 2 -pn-requester2 2718/tcp # PN REQUESTER 2 -# Edmund Chang -scan-change 2719/udp # Scan & Change -scan-change 2719/tcp # Scan & Change -# Alexander Raji -wkars 2720/udp # wkars -wkars 2720/tcp # wkars -# Barry Shelton -smart-diagnose 2721/udp # Smart Diagnose -smart-diagnose 2721/tcp # Smart Diagnose -# Geoffry Meek -proactivesrvr 2722/udp # Proactive Server -proactivesrvr 2722/tcp # Proactive Server -# Dalit Naor -watchdognt 2723/udp # WatchDog NT -watchdognt 2723/tcp # WatchDog NT -# Glen Sansoucie -qotps 2724/udp # qotps -qotps 2724/tcp # qotps -# Piotr Parlewicz -msolap-ptp2 2725/udp # MSOLAP PTP2 -msolap-ptp2 2725/tcp # MSOLAP PTP2 -# Cristian Petculescu -tams 2726/udp # TAMS -tams 2726/tcp # TAMS -# David Leinbach -mgcp-callagent 2727/udp # Media Gateway Control Protocol Call Agent -mgcp-callagent 2727/tcp # Media Gateway Control Protocol Call Agent -# Christian Huitema -sqdr 2728/udp # SQDR -sqdr 2728/tcp # SQDR -# Matthew Orzen -tcim-control 2729/udp # TCIM Control -tcim-control 2729/tcp # TCIM Control -# Dean Skelton -nec-raidplus 2730/udp # NEC RaidPlus -nec-raidplus 2730/tcp # NEC RaidPlus -# Yusuke Asai -fyre-messanger 2731/udp # Fyre Messagner -fyre-messanger 2731/tcp # Fyre Messanger -# Robert Waters -g5m 2732/udp # G5M -g5m 2732/tcp # G5M -# Graham Klyne -signet-ctf 2733/udp # Signet CTF -signet-ctf 2733/tcp # Signet CTF -# Greg Broiles -ccs-software 2734/udp # CCS Software -ccs-software 2734/tcp # CCS Software -# Bertus Jacobs -netiq-mc 2735/udp # NetIQ Monitor Console -netiq-mc 2735/tcp # NetIQ Monitor Console -# Scott Southard -radwiz-nms-srv 2736/udp # RADWIZ NMS SRV -radwiz-nms-srv 2736/tcp # RADWIZ NMS SRV -# Israel Shainert -srp-feedback 2737/udp # SRP Feedback -srp-feedback 2737/tcp # SRP Feedback -# Werner Almesberger -ndl-tcp-ois-gw 2738/udp # NDL TCP-OSI Gateway -ndl-tcp-ois-gw 2738/tcp # NDL TCP-OSI Gateway -# Martin Norman -tn-timing 2739/udp # TN Timing -tn-timing 2739/tcp # TN Timing -# Paul Roberts -alarm 2740/udp # Alarm -alarm 2740/tcp # Alarm -# Uriy Makasjuk -tsb 2741/udp # TSB -tsb 2741/tcp # TSB -tsb2 2742/udp # TSB2 -tsb2 2742/tcp # TSB2 -# Ashish Chatterjee -# -murx 2743/udp # murx -murx 2743/tcp # murx -# Thomas Kuiper -honyaku 2744/udp # honyaku -honyaku 2744/tcp # honyaku -# Yasunari Yamashita -urbisnet 2745/udp # URBISNET -urbisnet 2745/tcp # URBISNET -# Urbis.Net Ltd -cpudpencap 2746/udp # CPUDPENCAP -cpudpencap 2746/tcp # CPUDPENCAP -# Tamir Zegman -fjippol-swrly 2747/udp # -fjippol-swrly 2747/tcp # -fjippol-polsvr 2748/udp # -fjippol-polsvr 2748/tcp # -fjippol-cnsl 2749/udp # -fjippol-cnsl 2749/tcp # -fjippol-port1 2750/udp # -fjippol-port1 2750/tcp # -fjippol-port2 2751/udp # -fjippol-port2 2751/tcp # -# Shoichi Tachibana -rsisysaccess 2752/udp # RSISYS ACCESS -rsisysaccess 2752/tcp # RSISYS ACCESS -# Christophe Besant -de-spot 2753/udp # de-spot -de-spot 2753/tcp # de-spot -# Sanjay Parekh -apollo-cc 2754/udp # APOLLO CC -apollo-cc 2754/tcp # APOLLO CC -# Brand Communications -expresspay 2755/udp # Express Pay -expresspay 2755/tcp # Express Pay -# Ben Higgins -simplement-tie 2756/udp # simplement-tie -simplement-tie 2756/tcp # simplement-tie -# Tzvika Chumash -cnrp 2757/udp # CNRP -cnrp 2757/tcp # CNRP -# Jacob Ulmert -apollo-status 2758/udp # APOLLO Status -apollo-status 2758/tcp # APOLLO Status -apollo-gms 2759/udp # APOLLO GMS -apollo-gms 2759/tcp # APOLLO GMS -# Simon Hovell -sabams 2760/udp # Saba MS -sabams 2760/tcp # Saba MS -# Davoud Maha -dicom-iscl 2761/udp # DICOM ISCL -dicom-iscl 2761/tcp # DICOM ISCL -dicom-tls 2762/udp # DICOM TLS -dicom-tls 2762/tcp # DICOM TLS -# Lawrence Tarbox -desktop-dna 2763/udp # Desktop DNA -desktop-dna 2763/tcp # Desktop DNA -# Jon Walker -data-insurance 2764/udp # Data Insurance -data-insurance 2764/tcp # Data Insurance -# Brent Irwin -qip-audup 2765/udp # qip-audup -qip-audup 2765/tcp # qip-audup -# Mike Morgan -compaq-scp 2766/udp # Compaq SCP -compaq-scp 2766/tcp # Compaq SCP -# Ferruccio Barletta -uadtc 2767/udp # UADTC -uadtc 2767/tcp # UADTC -uacs 2768/udp # UACS -uacs 2768/tcp # UACS -# Vishwas Lele -singlept-mvs 2769/udp # Single Point MVS -singlept-mvs 2769/tcp # Single Point MVS -# Thomas Anderson -veronica 2770/udp # Veronica -veronica 2770/tcp # Veronica -# Jonas Oberg -vergencecm 2771/udp # Vergence CM -vergencecm 2771/tcp # Vergence CM -# Mark Morwood -auris 2772/udp # auris -auris 2772/tcp # auris -# Francisco Saez Arance -rbakcup1 2773/udp # RBackup Remote Backup -rbakcup1 2773/tcp # RBackup Remote Backup -rbakcup2 2774/udp # RBackup Remote Backup -rbakcup2 2774/tcp # RBackup Remote Backup -# Rob Cosgrove -smpp 2775/udp # SMPP -smpp 2775/tcp # SMPP -# Owen Sullivan -ridgeway1 2776/udp # Ridgeway Systems & Software -ridgeway1 2776/tcp # Ridgeway Systems & Software -ridgeway2 2777/udp # Ridgeway Systems & Software -ridgeway2 2777/tcp # Ridgeway Systems & Software -# Steve Read -gwen-sonya 2778/udp # Gwen-Sonya -gwen-sonya 2778/tcp # Gwen-Sonya -# Mark Hurst -lbc-sync 2779/udp # LBC Sync -lbc-sync 2779/tcp # LBC Sync -lbc-control 2780/udp # LBC Control -lbc-control 2780/tcp # LBC Control -# Keiji Michine -whosells 2781/udp # whosells -whosells 2781/tcp # whosells -# William Randolph Royere III -# -everydayrc 2782/udp # everydayrc -everydayrc 2782/tcp # everydayrc -# Ahti Heinla -aises 2783/udp # AISES -aises 2783/tcp # AISES -# Daniel Grazioli -www-dev 2784/udp # world wide web - development -www-dev 2784/tcp # world wide web - development -aic-np 2785/udp # aic-np -aic-np 2785/tcp # aic-np -# Brad Parker -aic-oncrpc 2786/udp # aic-oncrpc - Destiny MCD database -aic-oncrpc 2786/tcp # aic-oncrpc - Destiny MCD database -# Brad Parker -piccolo 2787/udp # piccolo - Cornerstone Software -piccolo 2787/tcp # piccolo - Cornerstone Software -# Dave Bellivea -fryeserv 2788/udp # NetWare Loadable Module - Seagate Software -fryeserv 2788/tcp # NetWare Loadable Module - Seagate Software -# Joseph LoPilato -# -media-agent 2789/udp # Media Agent -media-agent 2789/tcp # Media Agent -# Nitzan Daube -plgproxy 2790/udp # PLG Proxy -plgproxy 2790/tcp # PLG Proxy -# Charlie Hava -mtport-regist 2791/udp # MT Port Registrator -mtport-regist 2791/tcp # MT Port Registrator -# Maxim Tseitlin -f5-globalsite 2792/udp # f5-globalsite -f5-globalsite 2792/tcp # f5-globalsite -# Christian Saether -initlsmsad 2793/udp # initlsmsad -initlsmsad 2793/tcp # initlsmsad -# Kelly Green -aaftp 2794/udp # aaftp -aaftp 2794/tcp # aaftp -# E. Jay Berkenbilt -livestats 2795/udp # LiveStats -livestats 2795/tcp # LiveStats -# Chris Greene -ac-tech 2796/udp # ac-tech -ac-tech 2796/tcp # ac-tech -# Chiming Huang -esp-encap 2797/udp # esp-encap -esp-encap 2797/tcp # esp-encap -# Jorn Sierwald -tmesis-upshot 2798/udp # TMESIS-UPShot -tmesis-upshot 2798/tcp # TMESIS-UPShot -# Brian Schenkenberger -icon-discover 2799/udp # ICON Discover -icon-discover 2799/tcp # ICON Discover -# Alexander Falk -acc-raid 2800/udp # ACC RAID -acc-raid 2800/tcp # ACC RAID -# Scott St. Clair -igcp 2801/udp # IGCP -igcp 2801/tcp # IGCP -# David Hampson -veritas-udp1 2802/udp # Veritas UDP1 -veritas-tcp1 2802/tcp # Veritas TCP1 -# Russ Thrasher -btprjctrl 2803/udp # btprjctrl -btprjctrl 2803/tcp # btprjctrl -# Huw Thomas -telexis-vtu 2804/udp # Telexis VTU -telexis-vtu 2804/tcp # Telexis VTU -# Todd White -wta-wsp-s 2805/udp # WTA WSP-S -wta-wsp-s 2805/tcp # WTA WSP-S -# Sebastien Bury (WAP Forum) -# -cspuni 2806/udp # cspuni -cspuni 2806/tcp # cspuni -cspmulti 2807/udp # cspmulti -cspmulti 2807/tcp # cspmulti -# Terumasa Yoneda -j-lan-p 2808/udp # J-LAN-P -j-lan-p 2808/tcp # J-LAN-P -# Takeshi Sahara -corbaloc 2809/udp # CORBA LOC -corbaloc 2809/tcp # CORBA LOC -# Ted McFadden -netsteward 2810/udp # Active Net Steward -netsteward 2810/tcp # Active Net Steward -# Keith Morley -gsiftp 2811/udp # GSI FTP -gsiftp 2811/tcp # GSI FTP -# Von Welch -atmtcp 2812/udp # atmtcp -atmtcp 2812/tcp # atmtcp -# Werner Almesberger -llm-pass 2813/udp # llm-pass -llm-pass 2813/tcp # llm-pass -llm-csv 2814/udp # llm-csv -llm-csv 2814/tcp # llm-csv -# Glen Sansoucie -lbc-measure 2815/udp # LBC Measurement -lbc-measure 2815/tcp # LBC Measurement -lbc-watchdog 2816/udp # LBC Watchdog -lbc-watchdog 2816/tcp # LBC Watchdog -# Akiyoshi Ochi -nmsigport 2817/udp # NMSig Port -nmsigport 2817/tcp # NMSig Port -# Peter Egli -rmlnk 2818/udp # rmlnk -rmlnk 2818/tcp # rmlnk -fc-faultnotify 2819/udp # FC Fault Notification -fc-faultnotify 2819/tcp # FC Fault Notification -# Dave Watkins -univision 2820/udp # UniVision -univision 2820/tcp # UniVision -# Keith Ansell -vrts-at-port 2821/udp # VERITAS Authentication Service -vrts-at-port 2821/tcp # VERITAS Authentication Service -# Stefan Winkel -ka0wuc 2822/udp # ka0wuc -ka0wuc 2822/tcp # ka0wuc -# Kit Haskins -cqg-netlan 2823/udp # CQG Net/LAN -cqg-netlan 2823/tcp # CQG Net/LAN -cqg-netlan-1 2824/udp # CQG Net/Lan 1 -cqg-netlan-1 2824/tcp # CQG Net/LAN 1 -# Jeff Wood -# 2825 (unassigned) Possibly assigned -slc-systemlog 2826/udp # slc systemlog -slc-systemlog 2826/tcp # slc systemlog -slc-ctrlrloops 2827/udp # slc ctrlrloops -slc-ctrlrloops 2827/tcp # slc ctrlrloops -# Erwin Hogeweg -itm-lm 2828/udp # ITM License Manager -itm-lm 2828/tcp # ITM License Manager -# Miles O'Neal -silkp1 2829/udp # silkp1 -silkp1 2829/tcp # silkp1 -silkp2 2830/udp # silkp2 -silkp2 2830/tcp # silkp2 -silkp3 2831/udp # silkp3 -silkp3 2831/tcp # silkp3 -silkp4 2832/udp # silkp4 -silkp4 2832/tcp # silkp4 -# Erik Skyten -glishd 2833/udp # glishd -glishd 2833/tcp # glishd -# Darrell Schiebel -evtp 2834/udp # EVTP -evtp 2834/tcp # EVTP -evtp-data 2835/udp # EVTP-DATA -evtp-data 2835/tcp # EVTP-DATA -# Eric Bruno -catalyst 2836/udp # catalyst -catalyst 2836/tcp # catalyst -# Garret Tollkuhn -repliweb 2837/udp # Repliweb -repliweb 2837/tcp # Repliweb -# William Orme -starbot 2838/udp # Starbot -starbot 2838/tcp # Starbot -# Markus Sabadello -nmsigport 2839/udp # NMSigPort -nmsigport 2839/tcp # NMSigPort -# Peter Egli -l3-exprt 2840/udp # l3-exprt -l3-exprt 2840/tcp # l3-exprt -l3-ranger 2841/udp # l3-ranger -l3-ranger 2841/tcp # l3-ranger -l3-hawk 2842/udp # l3-hawk -l3-hawk 2842/tcp # l3-hawk -# Dolores Scott -pdnet 2843/udp # PDnet -pdnet 2843/tcp # PDnet -# Torsten Scheffler -bpcp-poll 2844/udp # BPCP POLL -bpcp-poll 2844/tcp # BPCP POLL -bpcp-trap 2845/udp # BPCP TRAP -bpcp-trap 2845/tcp # BPCP TRAP -# Steve Van Duser -# -aimpp-hello 2846/udp # AIMPP Hello -aimpp-hello 2846/tcp # AIMPP Hello -aimpp-port-req 2847/udp # AIMPP Port Req -aimpp-port-req 2847/tcp # AIMPP Port Req -# Brian Martinicky -# -amt-blc-port 2848/udp # AMT-BLC-PORT -amt-blc-port 2848/tcp # AMT-BLC-PORT -# Sandra Frulloni -fxp 2849/udp # FXP -fxp 2849/tcp # FXP -# Martin Lichtin -metaconsole 2850/udp # MetaConsole -metaconsole 2850/tcp # MetaConsole -# Rakesh Mahajan -webemshttp 2851/udp # webemshttp -webemshttp 2851/tcp # webemshttp -# Stephen Tsun -bears-01 2852/udp # bears-01 -bears-01 2852/tcp # bears-01 -# Bruce McKinnon -ispipes 2853/udp # ISPipes -ispipes 2853/tcp # ISPipes -# Rajesh Nandyalam -infomover 2854/udp # InfoMover -infomover 2854/tcp # InfoMover -# Carla Caputo -cesdinv 2856/udp # cesdinv -cesdinv 2856/tcp # cesdinv -# Yoshiaki Tokumoto -simctlp 2857/udp # SimCtIP -simctlp 2857/tcp # SimCtIP -# Christian Zietz -ecnp 2858/udp # ECNP -ecnp 2858/tcp # ECNP -# Robert Reimiller -activememory 2859/udp # Active Memory -activememory 2859/tcp # Active Memory -# Joe Graham -dialpad-voice1 2860/udp # Dialpad Voice 1 -dialpad-voice1 2860/tcp # Dialpad Voice 1 -dialpad-voice2 2861/udp # Dialpad Voice 2 -dialpad-voice2 2861/tcp # Dialpad Voice 2 -# Wongyu Cho -ttg-protocol 2862/udp # TTG Protocol -ttg-protocol 2862/tcp # TTG Protocol -# Mark Boler -sonardata 2863/udp # Sonar Data -sonardata 2863/tcp # Sonar Data -# Ian Higginbottom -astromed-main 2864/udp # main 5001 cmd -astromed-main 2864/tcp # main 5001 cmd -# Chris Tate -pit-vpn 2865/udp # pit-vpn -pit-vpn 2865/tcp # pit-vpn -# Norbert Sendetzky -iwlistener 2866/udp # iwlistener -iwlistener 2866/tcp # iwlistener -# Fred Surr -esps-portal 2867/udp # esps-portal -esps-portal 2867/tcp # esps-portal -# Nicholas Stowfis -npep-messaging 2868/udp # NPEP Messaging -npep-messaging 2868/tcp # NPEP Messaging -# Kristian A. Bognaes -icslap 2869/udp # ICSLAP -icslap 2869/tcp # ICSLAP -# Richard Lamb -daishi 2870/udp # daishi -daishi 2870/tcp # daishi -# Patrick Chipman -msi-selectplay 2871/udp # MSI Select Play -msi-selectplay 2871/tcp # MSI Select Play -# Paul Fonte -radix 2872/udp # RADIX -radix 2872/tcp # RADIX -# Stein Roger Skaflotten -# -paspar2-zoomin 2873/udp # PASPAR2 ZoomIn -paspar2-zoomin 2873/tcp # PASPAR2 ZoomIn -# Amonn David -dxmessagebase1 2874/udp # dxmessagebase1 -dxmessagebase1 2874/tcp # dxmessagebase1 -dxmessagebase2 2875/udp # dxmessagebase2 -dxmessagebase2 2875/tcp # dxmessagebase2 -# Ozz Nixon -sps-tunnel 2876/udp # SPS Tunnel -sps-tunnel 2876/tcp # SPS Tunnel -# Bill McIntosh -bluelance 2877/udp # BLUELANCE -bluelance 2877/tcp # BLUELANCE -# Michael Padrezas -aap 2878/udp # AAP -aap 2878/tcp # AAP -# Stephen Hanna -ucentric-ds 2879/udp # ucentric-ds -ucentric-ds 2879/tcp # ucentric-ds -# Alex Vasilevsky -synapse 2880/udp # Synapse Transport -synapse 2880/tcp # Synapse Transport -# Ali Fracyon -ndsp 2881/udp # NDSP -ndsp 2881/tcp # NDSP -ndtp 2882/udp # NDTP -ndtp 2882/tcp # NDTP -ndnp 2883/udp # NDNP -ndnp 2883/tcp # NDNP -# Khelben Blackstaff -flashmsg 2884/udp # Flash Msg -flashmsg 2884/tcp # Flash Msg -# Jeffrey Zinkerman -topflow 2885/udp # TopFlow -topflow 2885/tcp # TopFlow -# Ted Ross -responselogic 2886/udp # RESPONSELOGIC -responselogic 2886/tcp # RESPONSELOGIC -# Bruce Casey -aironetddp 2887/udp # aironet -aironetddp 2887/tcp # aironet -# Victor Griswold -spcsdlobby 2888/udp # SPCSDLOBBY -spcsdlobby 2888/tcp # SPCSDLOBBY -# Matthew Williams -rsom 2889/udp # RSOM -rsom 2889/tcp # RSOM -# Justine Higgins -cspclmulti 2890/udp # CSPCLMULTI -cspclmulti 2890/tcp # CSPCLMULTI -# Yoneda Terumasa -cinegrfx-elmd 2891/udp # CINEGRFX-ELMD License Manager -cinegrfx-elmd 2891/tcp # CINEGRFX-ELMD License Manager -# Greg Ercolano -snifferdata 2892/udp # SNIFFERDATA -snifferdata 2892/tcp # SNIFFERDATA -# Jeff Mangasarian -vseconnector 2893/udp # VSECONNECTOR -vseconnector 2893/tcp # VSECONNECTOR -# Ingo Franzki -abacus-remote 2894/udp # ABACUS-REMOTE -abacus-remote 2894/tcp # ABACUS-REMOTE -# Mike Bello -natuslink 2895/udp # NATUS LINK -natuslink 2895/tcp # NATUS LINK -# Jonathan Mergy -ecovisiong6-1 2896/udp # ECOVISIONG6-1 -ecovisiong6-1 2896/tcp # ECOVISIONG6-1 -# Henrik Holst -citrix-rtmp 2897/udp # Citrix RTMP -citrix-rtmp 2897/tcp # Citrix RTMP -# Myk Willis -appliance-cfg 2898/udp # APPLIANCE-CFG -appliance-cfg 2898/tcp # APPLIANCE-CFG -# Gary A. James -powergemplus 2899/udp # POWERGEMPLUS -powergemplus 2899/tcp # POWERGEMPLUS -# Koich Nakamura -quicksuite 2900/udp # QUICKSUITE -quicksuite 2900/tcp # QUICKSUITE -# William Egge -allstorcns 2901/udp # ALLSTORCNS -allstorcns 2901/tcp # ALLSTORCNS -# Steve Dobson -netaspi 2902/udp # NET ASPI -netaspi 2902/tcp # NET ASPI -# Johnson Luo -suitcase 2903/udp # SUITCASE -suitcase 2903/tcp # SUITCASE -# Milton E. Sagen -m2ua 2904/sctp # M2UA -m2ua 2904/udp # M2UA -m2ua 2904/tcp # M2UA -# Lyndon Ong -m3ua 2905/sctp # M3UA -m3ua 2905/udp # De-registered (2001 June 07) -m3ua 2905/tcp # M3UA -# Lyndon Ong -caller9 2906/udp # CALLER9 -caller9 2906/tcp # CALLER9 -# Shams Naqi -webmethods-b2b 2907/udp # WEBMETHODS B2B -webmethods-b2b 2907/tcp # WEBMETHODS B2B -# Joseph Hines -mao 2908/udp # mao -mao 2908/tcp # mao -# Marc Baudoin -funk-dialout 2909/udp # Funk Dialout -funk-dialout 2909/tcp # Funk Dialout -# Cimarron Boozer -tdaccess 2910/udp # TDAccess -tdaccess 2910/tcp # TDAccess -# Tom Haapanen -blockade 2911/udp # Blockade -blockade 2911/tcp # Blockade -# VP - Research & Development -epicon 2912/udp # Epicon -epicon 2912/tcp # Epicon -# Michael Khalandovsky -boosterware 2913/udp # Booster Ware -boosterware 2913/tcp # Booster Ware -# Ido Ben-David -gamelobby 2914/udp # Game Lobby -gamelobby 2914/tcp # Game Lobby -# Paul Ford-Hutchinson -tksocket 2915/udp # TK Socket -tksocket 2915/tcp # TK Socket -# Alan Fahrner -elvin_server 2916/udp # Elvin Server -elvin_server 2916/tcp # Elvin Server -elvin_client 2917/udp # Elvin Client -elvin_client 2917/tcp # Elvin Client -# David Arnold -kastenchasepad 2918/udp # Kasten Chase Pad -kastenchasepad 2918/tcp # Kasten Chase Pad -# Marc Gauthier -roboer 2919/udp # ROBOER -roboer 2919/tcp # ROBOER -# Paul Snook -roboeda 2920/udp # ROBOEDA -roboeda 2920/tcp # ROBOEDA -# Paul Snook -cesdcdman 2921/udp # CESD Contents Delivery Management -cesdcdman 2921/tcp # CESD Contents Delivery Management -# Shinya Abe -cesdcdtrn 2922/udp # CESD Contents Delivery Data Transfer -cesdcdtrn 2922/tcp # CESD Contents Delivery Data Transfer -# Shinya Abe -wta-wsp-wtp-s 2923/udp # WTA-WSP-WTP-S -wta-wsp-wtp-s 2923/tcp # WTA-WSP-WTP-S -# Sebastien Bury (WAP Forum) -# -precise-vip 2924/udp # PRECISE-VIP -precise-vip 2924/tcp # PRECISE-VIP -# Michael Landwehr -# 2925 Unassigned (FRP-Released 12/7/00) -mobile-file-dl 2926/udp # MOBILE-FILE-DL -mobile-file-dl 2926/tcp # MOBILE-FILE-DL -# Mitsuji Toda -unimobilectrl 2927/udp # UNIMOBILECTRL -unimobilectrl 2927/tcp # UNIMOBILECTRL -# Vikas -redstone-cpss 2928/udp # REDSTONE-CPSS -redstone-cpss 2928/tcp # REDSTONE-CPSS -# Jeff Looman -amx-webadmin 2929/udp # AMX-WEBADMIN -amx-webadmin 2929/tcp # AMX-WEBADMIN -# Mike Morris -amx-weblinx 2930/udp # AMX-WEBLINX -amx-weblinx 2930/tcp # AMX-WEBLINX -# Mike Morris -circle-x 2931/udp # Circle-X -circle-x 2931/tcp # Circle-X -# Norm Freedman -incp 2932/udp # INCP -incp 2932/tcp # INCP -# Keith Paulsen -4-tieropmgw 2933/udp # 4-TIER OPM GW -4-tieropmgw 2933/tcp # 4-TIER OPM GW -# Francois Peloffy -4-tieropmcli 2934/udp # 4-TIER OPM CLI -4-tieropmcli 2934/tcp # 4-TIER OPM CLI -# Francois Peloffy -qtp 2935/udp # QTP -qtp 2935/tcp # QTP -# Cameron Young -otpatch 2936/udp # OTPatch -otpatch 2936/tcp # OTPatch -# Thomas J. Theobald -pnaconsult-lm 2937/udp # PNACONSULT-LM -pnaconsult-lm 2937/tcp # PNACONSULT-LM -# Theo Nijssen -sm-pas-1 2938/udp # SM-PAS-1 -sm-pas-1 2938/tcp # SM-PAS-1 -sm-pas-2 2939/udp # SM-PAS-2 -sm-pas-2 2939/tcp # SM-PAS-2 -sm-pas-3 2940/udp # SM-PAS-3 -sm-pas-3 2940/tcp # SM-PAS-3 -sm-pas-4 2941/udp # SM-PAS-4 -sm-pas-4 2941/tcp # SM-PAS-4 -sm-pas-5 2942/udp # SM-PAS-5 -sm-pas-5 2942/tcp # SM-PAS-5 -# Tom Haapanen -ttnrepository 2943/udp # TTNRepository -ttnrepository 2943/tcp # TTNRepository -# Robert Orr -megaco-h248 2944/udp # Megaco H-248 -megaco-h248 2944/tcp # Megaco H-248 -h248-binary 2945/udp # H248 Binary -h248-binary 2945/tcp # H248 Binary -# Tom Taylor -fjsvmpor 2946/udp # FJSVmpor -fjsvmpor 2946/tcp # FJSVmpor -# Naoki Hayashi -gpsd 2947/udp # GPSD -gpsd 2947/tcp # GPSD -# Derrick J. Brashear -wap-push 2948/udp # WAP PUSH -wap-push 2948/tcp # WAP PUSH -wap-pushsecure 2949/udp # WAP PUSH SECURE -wap-pushsecure 2949/tcp # WAP PUSH SECURE -# WAP FORUM -esip 2950/udp # ESIP -esip 2950/tcp # ESIP -# David Stephenson -ottp 2951/udp # OTTP -ottp 2951/tcp # OTTP -# Brent Foster -mpfwsas 2952/udp # MPFWSAS -mpfwsas 2952/tcp # MPFWSAS -# Toru Murai -ovalarmsrv 2953/udp # OVALARMSRV -ovalarmsrv 2953/tcp # OVALARMSRV -ovalarmsrv-cmd 2954/udp # OVALARMSRV-CMD -ovalarmsrv-cmd 2954/tcp # OVALARMSRV-CMD -# Eric Pulsipher -csnotify 2955/udp # CSNOTIFY -csnotify 2955/tcp # CSNOTIFY -# Israel Beniaminy -ovrimosdbman 2956/udp # OVRIMOSDBMAN -ovrimosdbman 2956/tcp # OVRIMOSDBMAN -# Dimitrios Souflis -jmact5 2957/udp # JAMCT5 -jmact5 2957/tcp # JAMCT5 -jmact6 2958/udp # JAMCT6 -jmact6 2958/tcp # JAMCT6 -rmopagt 2959/udp # RMOPAGT -rmopagt 2959/tcp # RMOPAGT -# Shuji Okubo -dfoxserver 2960/udp # DFOXSERVER -dfoxserver 2960/tcp # DFOXSERVER -# David Holden -boldsoft-lm 2961/udp # BOLDSOFT-LM -boldsoft-lm 2961/tcp # BOLDSOFT-LM -# Fredrik Haglund -iph-policy-cli 2962/udp # IPH-POLICY-CLI -iph-policy-cli 2962/tcp # IPH-POLICY-CLI -iph-policy-adm 2963/udp # IPH-POLICY-ADM -iph-policy-adm 2963/tcp # IPH-POLICY-ADM -# Shai Herzog -bullant-srap 2964/udp # BULLANT SRAP -bullant-srap 2964/tcp # BULLANT SRAP -bullant-rap 2965/udp # BULLANT RAP -bullant-rap 2965/tcp # BULLANT RAP -# Michael Cahill -idp-infotrieve 2966/udp # IDP-INFOTRIEVE -idp-infotrieve 2966/tcp # IDP-INFOTRIEVE -# Kevin Bruckert -ssc-agent 2967/udp # SSC-AGENT -ssc-agent 2967/tcp # SSC-AGENT -# George Dzieciol -enpp 2968/udp # ENPP -enpp 2968/tcp # ENPP -# Kazuhito Gassho -essp 2969/udp # ESSP -essp 2969/tcp # ESSP -# Hitoshi Ishida -index-net 2970/udp # INDEX-NET -index-net 2970/tcp # INDEX-NET -# Chris J. Wren -netclip 2971/udp # NetClip clipboard daemon -netclip 2971/tcp # NetClip clipboard daemon -# Rudi Chiarito -pmsm-webrctl 2972/udp # PMSM Webrctl -pmsm-webrctl 2972/tcp # PMSM Webrctl -# Markus Michels -svnetworks 2973/udp # SV Networks -svnetworks 2973/tcp # SV Networks -# Sylvia Siu -signal 2974/udp # Signal -signal 2974/tcp # Signal -# Wyatt Williams -fjmpcm 2975/udp # Fujitsu Configuration Management Service -fjmpcm 2975/tcp # Fujitsu Configuration Management Service -# Hiroki Kawano -cns-srv-port 2976/udp # CNS Server Port -cns-srv-port 2976/tcp # CNS Server Port -# Ram Golla -ttc-etap-ns 2977/udp # TTCs Enterprise Test Access Protocol - NS -ttc-etap-ns 2977/tcp # TTCs Enterprise Test Access Protocol - NS -ttc-etap-ds 2978/udp # TTCs Enterprise Test Access Protocol - DS -ttc-etap-ds 2978/tcp # TTCs Enterprise Test Access Protocol - DS -# Daniel Becker -h263-video 2979/udp # H.263 Video Streaming -h263-video 2979/tcp # H.263 Video Streaming -# Jauvane C. de Oliveira -wimd 2980/udp # Instant Messaging Service -wimd 2980/tcp # Instant Messaging Service -# Kevin Birch -mylxamport 2981/udp # MYLXAMPORT -mylxamport 2981/tcp # MYLXAMPORT -# Wei Gao -iwb-whiteboard 2982/udp # IWB-WHITEBOARD -iwb-whiteboard 2982/tcp # IWB-WHITEBOARD -# David W. Radcliffe -netplan 2983/udp # NETPLAN -netplan 2983/tcp # NETPLAN -# Thomas Driemeyer -hpidsadmin 2984/udp # HPIDSADMIN -hpidsadmin 2984/tcp # HPIDSADMIN -hpidsagent 2985/udp # HPIDSAGENT -hpidsagent 2985/tcp # HPIDSAGENT -# John Trudeau -stonefalls 2986/udp # STONEFALLS -stonefalls 2986/tcp # STONEFALLS -# Scott Grau -identify 2987/udp # identify -identify 2987/tcp # identify -hippad 2988/udp # HIPPA Reporting Protocol -hippad 2988/tcp # HIPPA Reporting Protocol -# William Randolph Royere III -# -zarkov 2989/udp # ZARKOV Intelligent Agent Communication -zarkov 2989/tcp # ZARKOV Intelligent Agent Communication -# Robin Felix -boscap 2990/udp # BOSCAP -boscap 2990/tcp # BOSCAP -# Dirk Hillbrecht -wkstn-mon 2991/udp # WKSTN-MON -wkstn-mon 2991/tcp # WKSTN-MON -# William David -itb301 2992/udp # ITB301 -itb301 2992/tcp # ITB301 -# Bodo Rueskamp -veritas-vis1 2993/udp # VERITAS VIS1 -veritas-vis1 2993/tcp # VERITAS VIS1 -veritas-vis2 2994/udp # VERITAS VIS2 -veritas-vis2 2994/tcp # VERITAS VIS2 -# Dinkar Chivaluri -idrs 2995/udp # IDRS -idrs 2995/tcp # IDRS -# Jeff Eaton -vsixml 2996/udp # vsixml -vsixml 2996/tcp # vsixml -# Rob Juergens -rebol 2997/udp # REBOL -rebol 2997/tcp # REBOL -# Holger Kruse -realsecure 2998/udp # Real Secure -realsecure 2998/tcp # Real Secure -# Tim Farley -remoteware-un 2999/udp # RemoteWare Unassigned -remoteware-un 2999/tcp # RemoteWare Unassigned -# Tim Farley -hbci 3000/udp # HBCI -hbci 3000/tcp # HBCI -# Kurt Haubner -# The following entry records an unassigned but widespread use -remoteware-cl 3000/udp # RemoteWare Client -remoteware-cl 3000/tcp # RemoteWare Client -# Tim Farley -redwood-broker 3001/udp # Redwood Broker -redwood-broker 3001/tcp # Redwood Broker -# Joseph Morrison -exlm-agent 3002/udp # EXLM Agent -exlm-agent 3002/tcp # EXLM Agent -# Randy Martin -# The following entry records an unassigned but widespread use -remoteware-srv 3002/udp # RemoteWare Server -remoteware-srv 3002/tcp # RemoteWare Server -# Tim Farley -cgms 3003/udp # CGMS -cgms 3003/tcp # CGMS -# Jim Mazzonna -csoftragent 3004/udp # Csoft Agent -csoftragent 3004/tcp # Csoft Agent -# Nedelcho Stanev -geniuslm 3005/udp # Genius License Manager -geniuslm 3005/tcp # Genius License Manager -# Jakob Spies -ii-admin 3006/udp # Instant Internet Admin -ii-admin 3006/tcp # Instant Internet Admin -# Lewis Donzis -lotusmtap 3007/udp # Lotus Mail Tracking Agent Protocol -lotusmtap 3007/tcp # Lotus Mail Tracking Agent Protocol -# Ken Lin -midnight-tech 3008/udp # Midnight Technologies -midnight-tech 3008/tcp # Midnight Technologies -# Kyle Unice -pxc-ntfy 3009/udp # PXC-NTFY -pxc-ntfy 3009/tcp # PXC-NTFY -# Takeshi Nishizawa -ping-pong 3010/udp # Telerate Workstation -gw 3010/tcp # Telerate Workstation -# Timo Sivonen -trusted-web 3011/udp # Trusted Web -trusted-web 3011/tcp # Trusted Web -twsdss 3012/udp # Trusted Web Client -twsdss 3012/tcp # Trusted Web Client -# Alex Duncan -gilatskysurfer 3013/udp # Gilat Sky Surfer -gilatskysurfer 3013/tcp # Gilat Sky Surfer -# Yossi Gal -broker_service 3014/udp # Broker Service -broker_service 3014/tcp # Broker Service -# Dale Bethers -nati-dstp 3015/udp # NATI DSTP -nati-dstp 3015/tcp # NATI DSTP -# Paul Austin -notify_srvr 3016/udp # Notify Server -notify_srvr 3016/tcp # Notify Server -# Hugo Parra -event_listener 3017/udp # Event Listener -event_listener 3017/tcp # Event Listener -# Ted Tronson -srvc_registry 3018/udp # Service Registry -srvc_registry 3018/tcp # Service Registry -# Mark Killgore -resource_mgr 3019/udp # Resource Manager -resource_mgr 3019/tcp # Resource Manager -# Gary Glover -cifs 3020/udp # CIFS -cifs 3020/tcp # CIFS -# Paul Leach -agriserver 3021/udp # AGRI Server -agriserver 3021/tcp # AGRI Server -# Frank Neulichedl -csregagent 3022/udp # CSREGAGENT -csregagent 3022/tcp # CSREGAGENT -# Nedelcho Stanev -magicnotes 3023/udp # magicnotes -magicnotes 3023/tcp # magicnotes -# Karl Edwall -nds_sso 3024/udp # NDS_SSO -nds_sso 3024/tcp # NDS_SSO -# Mel Oyler -arepa-raft 3025/udp # Arepa Raft -arepa-raft 3025/tcp # Arepa Raft -# Mark Ellison -agri-gateway 3026/udp # AGRI Gateway -agri-gateway 3026/tcp # AGRI Gateway -# Agri Datalog -LiebDevMgmt_C 3027/udp # LiebDevMgmt_C -LiebDevMgmt_C 3027/tcp # LiebDevMgmt_C -LiebDevMgmt_DM 3028/udp # LiebDevMgmt_DM -LiebDevMgmt_DM 3028/tcp # LiebDevMgmt_DM -LiebDevMgmt_A 3029/udp # LiebDevMgmt_A -LiebDevMgmt_A 3029/tcp # LiebDevMgmt_A -# Mike Velten -arepa-cas 3030/udp # Arepa Cas -arepa-cas 3030/tcp # Arepa Cas -# Seth Silverman -eppc 3031/udp # Remote AppleEvents/PPC Toolbox -eppc 3031/tcp # Remote AppleEvents/PPC Toolbox -# Steve Zellers -redwood-chat 3032/udp # Redwood Chat -redwood-chat 3032/tcp # Redwood Chat -# Songwon Chi -pdb 3033/udp # PDB -pdb 3033/tcp # PDB -# Don Bowman -osmosis-aeea 3034/udp # Osmosis / Helix (R) AEEA Port -osmosis-aeea 3034/tcp # Osmosis / Helix (R) AEEA Port -# Larry Atkin -fjsv-gssagt 3035/udp # FJSV gssagt -fjsv-gssagt 3035/tcp # FJSV gssagt -# Tomoji Koike -hagel-dump 3036/udp # Hagel DUMP -hagel-dump 3036/tcp # Hagel DUMP -# Haim Gelfenbeyn -hp-san-mgmt 3037/udp # HP SAN Mgmt -hp-san-mgmt 3037/tcp # HP SAN Mgmt -# Steve Britt -santak-ups 3038/udp # Santak UPS -santak-ups 3038/tcp # Santak UPS -# Tom Liu -cogitate 3039/udp # Cogitate, Inc. -cogitate 3039/tcp # Cogitate, Inc. -# Jim Harlan -tomato-springs 3040/udp # Tomato Springs -tomato-springs 3040/tcp # Tomato Springs -# Jack Waller III -di-traceware 3041/udp # di-traceware -di-traceware 3041/tcp # di-traceware -# Carlos Hung -journee 3042/udp # journee -journee 3042/tcp # journee -# Kevin Calman -brp 3043/udp # BRP -brp 3043/tcp # BRP -# Greg Gee -epp 3044/udp # EndPoint Protocol -epp 3044/tcp # EndPoint Protocol -# Stephen Cipolli -responsenet 3045/udp # ResponseNet -responsenet 3045/tcp # ResponseNet -# Chul Yoon -di-ase 3046/udp # di-ase -di-ase 3046/tcp # di-ase -# Carlos Hung -hlserver 3047/udp # Fast Security HL Server -hlserver 3047/tcp # Fast Security HL Server -# Michael Zunke -pctrader 3048/udp # Sierra Net PC Trader -pctrader 3048/tcp # Sierra Net PC Trader -# Chris Hahn -nsws 3049/udp # NSWS -nsws 3049/tcp # NSWS -# Ray Gwinn -gds_db 3050/udp # gds_db -gds_db 3050/tcp # gds_db -# Madhukar N. Thakur -galaxy-server 3051/udp # Galaxy Server -galaxy-server 3051/tcp # Galaxy Server -# Michael Andre -apc-3052 3052/udp # APC 3052 -apc-3052 3052/tcp # APC 3052 -# American Power Conversion -dsom-server 3053/udp # dsom-server -dsom-server 3053/tcp # dsom-server -# Daniel Sisk -amt-cnf-prot 3054/udp # AMT CNF PROT -amt-cnf-prot 3054/tcp # AMT CNF PROT -# Marco Marcucci -policyserver 3055/udp # Policy Server -policyserver 3055/tcp # Policy Server -# Mark Garti -cdl-server 3056/udp # CDL Server -cdl-server 3056/tcp # CDL Server -# Paul Roberts -goahead-fldup 3057/udp # GoAhead FldUp -goahead-fldup 3057/tcp # GoAhead FldUp -# Alan Pickrell -videobeans 3058/udp # videobeans -videobeans 3058/tcp # videobeans -# Hiroyuki Takahashi -qsoft 3059/udp # qsoft -qsoft 3059/tcp # qsoft -# James Kunz -interserver 3060/udp # interserver -interserver 3060/tcp # interserver -# Madhukar N. Thakur -cautcpd 3061/udp # cautcpd -cautcpd 3061/tcp # cautcpd -ncacn-ip-tcp 3062/udp # ncacn-ip-tcp -ncacn-ip-tcp 3062/tcp # ncacn-ip-tcp -ncadg-ip-udp 3063/udp # ncadg-ip-udp -ncadg-ip-udp 3063/tcp # ncadg-ip-udp -# Gabi Kalmar -rprt 3064/udp # Remote Port Redirector -rprt 3064/tcp # Remote Port Redirector -# Robin Johnston -slinterbase 3065/udp # slinterbase -slinterbase 3065/tcp # slinterbase -# Bie Tie -netattachsdmp 3066/udp # NETATTACHSDMP -netattachsdmp 3066/tcp # NETATTACHSDMP -# Mike Young -fjhpjp 3067/udp # FJHPJP -fjhpjp 3067/tcp # FJHPJP -# Ryozo Furutani -ls3bcast 3068/udp # ls3 Broadcast -ls3bcast 3068/tcp # ls3 Broadcast -ls3 3069/udp # ls3 -ls3 3069/tcp # ls3 -# Andrei Tsyganenko -mgxswitch 3070/udp # MGXSWITCH -mgxswitch 3070/tcp # MGXSWITCH -# George Walter -csd-mgmt-port 3071/udp # ContinuStor Manager Port -csd-mgmt-port 3071/tcp # ContinuStor Manager Port -csd-monitor 3072/udp # ContinuStor Monitor Port -csd-monitor 3072/tcp # ContinuStor Monitor Port -# Ray Jantz -vcrp 3073/udp # Very simple chatroom prot -vcrp 3073/tcp # Very simple chatroom prot -# Andreas Wurf -xbox 3074/udp # Xbox game port -xbox 3074/tcp # Xbox game port -# Damon Danieli -orbix-locator 3075/udp # Orbix 2000 Locator -orbix-locator 3075/tcp # Orbix 2000 Locator -orbix-config 3076/udp # Orbix 2000 Config -orbix-config 3076/tcp # Orbix 2000 Config -orbix-loc-ssl 3077/udp # Orbix 2000 Locator SSL -orbix-loc-ssl 3077/tcp # Orbix 2000 Locator SSL -orbix-cfg-ssl 3078/udp # Orbix 2000 Locator SSL -orbix-cfg-ssl 3078/tcp # Orbix 2000 Locator SSL -# Eric Newcomer -lv-frontpanel 3079/udp # LV Front Panel -lv-frontpanel 3079/tcp # LV Front Panel -# Darshan Shah -stm_pproc 3080/udp # stm_pproc -stm_pproc 3080/tcp # stm_pproc -# Paul McGinnis -tl1-lv 3081/udp # TL1-LV -tl1-lv 3081/tcp # TL1-LV -tl1-raw 3082/udp # TL1-RAW -tl1-raw 3082/tcp # TL1-RAW -tl1-telnet 3083/udp # TL1-TELNET -tl1-telnet 3083/tcp # TL1-TELNET -# SONET Internetworking Forum (SIF) -# - SONET Contact -itm-mccs 3084/udp # ITM-MCCS -itm-mccs 3084/tcp # ITM-MCCS -# Alain Callebaut -pcihreq 3085/udp # PCIHReq -pcihreq 3085/tcp # PCIHReq -# Paul Sanders -jdl-dbkitchen 3086/udp # JDL-DBKitchen -jdl-dbkitchen 3086/tcp # JDL-DBKitchen -# Hideo Wakabayashi -asoki-sma 3087/udp # Asoki SMA -asoki-sma 3087/tcp # Asoki SMA -# Andrew Mossberg -xdtp 3088/udp # eXtensible Data Transfer Protocol -xdtp 3088/tcp # eXtensible Data Transfer Protocol -# Michael Shearson -ptk-alink 3089/udp # ParaTek Agent Linking -ptk-alink 3089/tcp # ParaTek Agent Linking -# Robert Hodgson -rtss 3090/udp # Rappore Session Services -rtss 3090/tcp # Rappore Session Services -# Peter Boucher -1ci-smcs 3091/udp # 1Ci Server Management -1ci-smcs 3091/tcp # 1Ci Server Management -# Ralf Bensmann -njfss 3092/udp # Netware sync services -njfss 3092/tcp # Netware sync services -# Gordon Ross -rapidmq-center 3093/udp # Jiiva RapidMQ Center -rapidmq-center 3093/tcp # Jiiva RapidMQ Center -rapidmq-reg 3094/udp # Jiiva RapidMQ Registry -rapidmq-reg 3094/tcp # Jiiva RapidMQ Registry -# Mark Ericksen -panasas 3095/udp # Panasas rendevous port -panasas 3095/tcp # Panasas rendevous port -# Peter Berger -ndl-aps 3096/udp # Active Print Server Port -ndl-aps 3096/tcp # Active Print Server Port -# Martin Norman -# 3097/tcp Reserved -# 3097/udp Reserved -itu-bicc-stc 3097/sctp # ITU-T Q.1902.1/Q.2150.3 -# Greg Sidebottom -umm-port 3098/udp # Universal Message Manager -umm-port 3098/tcp # Universal Message Manager -# Phil Braham -chmd 3099/udp # CHIPSY Machine Daemon -chmd 3099/tcp # CHIPSY Machine Daemon -# Trond Borsting -opcon-xps 3100/udp # OpCon/xps -opcon-xps 3100/tcp # OpCon/xps -# David Bourland -hp-pxpib 3101/udp # HP PolicyXpert PIB Server -hp-pxpib 3101/tcp # HP PolicyXpert PIB Server -# Brian O'Keefe -slslavemon 3102/udp # SoftlinK Slave Mon Port -slslavemon 3102/tcp # SoftlinK Slave Mon Port -# Moshe Livne -autocuesmi 3103/udp # Autocue SMI Protocol -autocuesmi 3103/tcp # Autocue SMI Protocol -autocuetime 3104/udp # Autocue Time Service -autocuelog 3104/tcp # Autocue Logger Protocol -# Geoff Back -cardbox 3105/udp # Cardbox -cardbox 3105/tcp # Cardbox -cardbox-http 3106/udp # Cardbox HTTP -cardbox-http 3106/tcp # Cardbox HTTP -# Martin Kochanski -business 3107/udp # Business protocol -business 3107/tcp # Business protocol -geolocate 3108/udp # Geolocate protocol -geolocate 3108/tcp # Geolocate protocol -personnel 3109/udp # Personnel protocol -personnel 3109/tcp # Personnel protocol -# William Randolph Royere III -# -sim-control 3110/udp # simulator control port -sim-control 3110/tcp # simulator control port -# Ian Bell -wsynch 3111/udp # Web Synchronous Services -wsynch 3111/tcp # Web Synchronous Services -# Valery Fremaux -ksysguard 3112/udp # KDE System Guard -ksysguard 3112/tcp # KDE System Guard -# Chris Schlaeger -cs-auth-svr 3113/udp # CS-Authenticate Svr Port -cs-auth-svr 3113/tcp # CS-Authenticate Svr Port -# Cliff Diamond -# Andy Georgiou -ccmad 3114/udp # CCM AutoDiscover -ccmad 3114/tcp # CCM AutoDiscover -# Ram Sudama -mctet-master 3115/udp # MCTET Master -mctet-master 3115/tcp # MCTET Master -mctet-gateway 3116/udp # MCTET Gateway -mctet-gateway 3116/tcp # MCTET Gateway -mctet-jserv 3117/udp # MCTET Jserv -mctet-jserv 3117/tcp # MCTET Jserv -# Manuel Veloso -pkagent 3118/udp # PKAgent -pkagent 3118/tcp # PKAgent -# Michael Douglass -d2000kernel 3119/udp # D2000 Kernel Port -d2000kernel 3119/tcp # D2000 Kernel Port -d2000webserver 3120/udp # D2000 Webserver Port -d2000webserver 3120/tcp # D2000 Webserver Port -# Tomas Rajcan -epp-temp 3121/udp # Extensible Provisioning Protocol -epp-temp 3121/tcp # Extensible Provisioning Protocol -# Scott Hollenbeck -vtr-emulator 3122/udp # MTI VTR Emulator port -vtr-emulator 3122/tcp # MTI VTR Emulator port -# John Mertus -edix 3123/udp # EDI Translation Protocol -edix 3123/tcp # EDI Translation Protocol -# William Randolph Royere III -beacon-port 3124/udp # Beacon Port -beacon-port 3124/tcp # Beacon Port -# James Paul Duncan -a13-an 3125/udp # A13-AN Interface -a13-an 3125/tcp # A13-AN Interface -# Douglas Knisely -ms-dotnetster 3126/udp # Microsoft .NETster Port -ms-dotnetster 3126/tcp # Microsoft .NETster Port -# Dave Mendlen -ctx-bridge 3127/udp # CTX Bridge Port -ctx-bridge 3127/tcp # CTX Bridge Port -# Alexander Dubrovsky -ndl-aas 3128/udp # Active API Server Port -ndl-aas 3128/tcp # Active API Server Port -# Martin Norman -netport-id 3129/udp # NetPort Discovery Port -netport-id 3129/tcp # NetPort Discovery Port -# P.T.K. Farrar -icpv2 3130/udp # ICPv2 -icpv2 3130/tcp # ICPv2 -# Duane Wessels -netbookmark 3131/udp # Net Book Mark -netbookmark 3131/tcp # Net Book Mark -# Yiftach Ravid -ms-rule-engine 3132/udp # Microsoft Business Rule Engine Update Service -ms-rule-engine 3132/tcp # Microsoft Business Rule Engine Update Service -# Anush Kumar -prism-deploy 3133/udp # Prism Deploy User Port -prism-deploy 3133/tcp # Prism Deploy User Port -# Joan Linck -ecp 3134/udp # Extensible Code Protocol -ecp 3134/tcp # Extensible Code Protocol -# Jim Trek -# Mark Bocko -peerbook-port 3135/udp # PeerBook Port -peerbook-port 3135/tcp # PeerBook Port -# John Flowers -grubd 3136/udp # Grub Server Port -grubd 3136/tcp # Grub Server Port -# Kord Campbell -rtnt-1 3137/udp # rtnt-1 data packets -rtnt-1 3137/tcp # rtnt-1 data packets -rtnt-2 3138/udp # rtnt-2 data packets -rtnt-2 3138/tcp # rtnt-2 data packets -# Ron Muellerschoen -incognitorv 3139/udp # Incognito Rendez-Vous -incognitorv 3139/tcp # Incognito Rendez-Vous -# Stephane Bourque -ariliamulti 3140/udp # Arilia Multiplexor -ariliamulti 3140/tcp # Arilia Multiplexor -# Stephane Bourque -vmodem 3141/udp # VMODEM -vmodem 3141/tcp # VMODEM -# Ray Gwinn -rdc-wh-eos 3142/udp # RDC WH EOS -rdc-wh-eos 3142/tcp # RDC WH EOS -# Udi Nir -seaview 3143/udp # Sea View -seaview 3143/tcp # Sea View -# Jim Flaherty -tarantella 3144/udp # Tarantella -tarantella 3144/tcp # Tarantella -# Roger Binns -csi-lfap 3145/udp # CSI-LFAP -csi-lfap 3145/tcp # CSI-LFAP -# Paul Amsden -bears-02 3146/udp # bears-02 -bears-02 3146/tcp # bears-02 -# Bruce McKinnon -rfio 3147/udp # RFIO -rfio 3147/tcp # RFIO -# Frederic Hemmer -nm-game-admin 3148/udp # NetMike Game Administrator -nm-game-admin 3148/tcp # NetMike Game Administrator -nm-game-server 3149/udp # NetMike Game Server -nm-game-server 3149/tcp # NetMike Game Server -nm-asses-admin 3150/udp # NetMike Assessor Administrator -nm-asses-admin 3150/tcp # NetMike Assessor Administrator -nm-assessor 3151/udp # NetMike Assessor -nm-assessor 3151/tcp # NetMike Assessor -# Andrew Sharpe -feitianrockey 3152/udp # FeiTian Port -feitianrockey 3152/tcp # FeiTian Port -# Huang Yu -s8-client-port 3153/udp # S8Cargo Client Port -s8-client-port 3153/tcp # S8Cargo Client Port -# Jon S. Kyle -ccmrmi 3154/udp # ON RMI Registry -ccmrmi 3154/tcp # ON RMI Registry -# Ram Sudama -jpegmpeg 3155/udp # JpegMpeg Port -jpegmpeg 3155/tcp # JpegMpeg Port -# Richard Bassous -indura 3156/udp # Indura Collector -indura 3156/tcp # Indura Collector -# Bruce Kosbab -e3consultants 3157/udp # CCC Listener Port -e3consultants 3157/tcp # CCC Listener Port -# Brian Carnell -stvp 3158/udp # SmashTV Protocol -stvp 3158/tcp # SmashTV Protocol -# Christian Wolff -navegaweb-port 3159/udp # NavegaWeb Tarification -navegaweb-port 3159/tcp # NavegaWeb Tarification -# Miguel Angel Fernandez -tip-app-server 3160/udp # TIP Application Server -tip-app-server 3160/tcp # TIP Application Server -# Olivier Mascia -doc1lm 3161/udp # DOC1 License Manager -doc1lm 3161/tcp # DOC1 License Manager -# Greg Goodson -sflm 3162/udp # SFLM -sflm 3162/tcp # SFLM -# Keith Turner -res-sap 3163/udp # RES-SAP -res-sap 3163/tcp # RES-SAP -# Bob Janssen -imprs 3164/udp # IMPRS -imprs 3164/tcp # IMPRS -# Lars Bohn -newgenpay 3165/udp # Newgenpay Engine Service -newgenpay 3165/tcp # Newgenpay Engine Service -# Ilan Zisser -qrepos 3166/udp # Quest Repository -qrepos 3166/tcp # Quest Repository -# Fred Surr -poweroncontact 3167/udp # poweroncontact -poweroncontact 3167/tcp # poweroncontact -poweronnud 3168/udp # poweronnud -poweronnud 3168/tcp # poweronnud -# Paul Cone -serverview-as 3169/udp # SERVERVIEW-AS -serverview-as 3169/tcp # SERVERVIEW-AS -serverview-asn 3170/udp # SERVERVIEW-ASN -serverview-asn 3170/tcp # SERVERVIEW-ASN -serverview-gf 3171/udp # SERVERVIEW-GF -serverview-gf 3171/tcp # SERVERVIEW-GF -serverview-rm 3172/udp # SERVERVIEW-RM -serverview-rm 3172/tcp # SERVERVIEW-RM -serverview-icc 3173/udp # SERVERVIEW-ICC -serverview-icc 3173/tcp # SERVERVIEW-ICC -# Guenther Kroenert -# -armi-server 3174/udp # ARMI Server -armi-server 3174/tcp # ARMI Server -# Bobby Martin -t1-e1-over-ip 3175/udp # T1_E1_Over_IP -t1-e1-over-ip 3175/tcp # T1_E1_Over_IP -# Mark Doyle -ars-master 3176/udp # ARS Master -ars-master 3176/tcp # ARS Master -# Ade Adebayo -phonex-port 3177/udp # Phonex Protocol -phonex-port 3177/tcp # Phonex Protocol -# Doug Grover -radclientport 3178/udp # Radiance UltraEdge Port -radclientport 3178/tcp # Radiance UltraEdge Port -# Sri Subramaniam -h2gf-w-2m 3179/udp # H2GF W.2m Handover prot. -h2gf-w-2m 3179/tcp # H2GF W.2m Handover prot. -# Arne Norefors -mc-brk-srv 3180/udp # Millicent Broker Server -mc-brk-srv 3180/tcp # Millicent Broker Server -# Steve Glassman -bmcpatrolagent 3181/udp # BMC Patrol Agent -bmcpatrolagent 3181/tcp # BMC Patrol Agent -bmcpatrolrnvu 3182/udp # BMC Patrol Rendezvous -bmcpatrolrnvu 3182/tcp # BMC Patrol Rendezvous -# Eric Anderson -cops-tls 3183/udp # COPS/TLS -cops-tls 3183/tcp # COPS/TLS -# Mark Stevens -apogeex-port 3184/udp # ApogeeX Port -apogeex-port 3184/tcp # ApogeeX Port -# Tom Nys -smpppd 3185/udp # SuSE Meta PPPD -smpppd 3185/tcp # SuSE Meta PPPD -# Arvin Schnell -iiw-port 3186/udp # IIW Monitor User Port -iiw-port 3186/tcp # IIW Monitor User Port -# Corey Burnett -odi-port 3187/udp # Open Design Listen Port -odi-port 3187/tcp # Open Design Listen Port -# Phivos Aristides -brcm-comm-port 3188/udp # Broadcom Port -brcm-comm-port 3188/tcp # Broadcom Port -# Thomas L. Johnson -pcle-infex 3189/udp # Pinnacle Sys InfEx Port -pcle-infex 3189/tcp # Pinnacle Sys InfEx Port -# Anthon van der Neut -csvr-proxy 3190/udp # ConServR Proxy -csvr-proxy 3190/tcp # ConServR Proxy -csvr-sslproxy 3191/udp # ConServR SSL Proxy -csvr-sslproxy 3191/tcp # ConServR SSL Proxy -# Mikhail Kruk -firemonrcc 3192/udp # FireMon Revision Control -firemonrcc 3192/tcp # FireMon Revision Control -# Michael Bishop -cordataport 3193/udp # Cordaxis Data Port -cordataport 3193/tcp # Cordaxis Data Port -# Jay Fesco -magbind 3194/udp # Rockstorm MAG protocol -magbind 3194/tcp # Rockstorm MAG protocol -# Jens Nilsson -ncu-1 3195/udp # Network Control Unit -ncu-1 3195/tcp # Network Control Unit -ncu-2 3196/udp # Network Control Unit -ncu-2 3196/tcp # Network Control Unit -# Charlie Hundre -embrace-dp-s 3197/udp # Embrace Device Protocol Server -embrace-dp-s 3197/tcp # Embrace Device Protocol Server -embrace-dp-c 3198/udp # Embrace Device Protocol Client -embrace-dp-c 3198/tcp # Embrace Device Protocol Client -# Elliot Schwartz -dmod-workspace 3199/udp # DMOD WorkSpace -dmod-workspace 3199/tcp # DMOD WorkSpace -# Nick Plante -tick-port 3200/udp # Press-sense Tick Port -tick-port 3200/tcp # Press-sense Tick Port -# Boris Svetlitsky -cpq-tasksmart 3201/udp # CPQ-TaskSmart -cpq-tasksmart 3201/tcp # CPQ-TaskSmart -# Jackie Lau -intraintra 3202/udp # IntraIntra -intraintra 3202/tcp # IntraIntra -# Matthew Asham -netwatcher-mon 3203/udp # Network Watcher Monitor -netwatcher-mon 3203/tcp # Network Watcher Monitor -netwatcher-db 3204/udp # Network Watcher DB Access -netwatcher-db 3204/tcp # Network Watcher DB Access -# Hirokazu Fujisawa -isns 3205/udp # iSNS Server Port -isns 3205/tcp # iSNS Server Port -# Josh Tseng -ironmail 3206/udp # IronMail POP Proxy -ironmail 3206/tcp # IronMail POP Proxy -# Mike Hudack -vx-auth-port 3207/udp # Veritas Authentication Port -vx-auth-port 3207/tcp # Veritas Authentication Port -# Senthil Ponnuswamy -pfu-prcallback 3208/udp # PFU PR Callback -pfu-prcallback 3208/tcp # PFU PR Callback -# Tetsuharu Hanada -netwkpathengine 3209/udp # HP OpenView Network Path Engine Server -netwkpathengine 3209/tcp # HP OpenView Network Path Engine Server -# Anthony Walker -flamenco-proxy 3210/udp # Flamenco Networks Proxy -flamenco-proxy 3210/tcp # Flamenco Networks Proxy -# Corey Corrick -avsecuremgmt 3211/udp # Avocent Secure Management -avsecuremgmt 3211/tcp # Avocent Secure Management -# Brian S. Stewart -surveyinst 3212/udp # Survey Instrument -surveyinst 3212/tcp # Survey Instrument -# Al Amet -neon24x7 3213/udp # NEON 24X7 Mission Control -neon24x7 3213/tcp # NEON 24X7 Mission Control -# Tony Lubrano -jmq-daemon-1 3214/udp # JMQ Daemon Port 1 -jmq-daemon-1 3214/tcp # JMQ Daemon Port 1 -jmq-daemon-2 3215/udp # JMQ Daemon Port 2 -jmq-daemon-2 3215/tcp # JMQ Daemon Port 2 -# Martin West -ferrari-foam 3216/udp # Ferrari electronic FOAM -ferrari-foam 3216/tcp # Ferrari electronic FOAM -# Johann Deutinger -unite 3217/udp # Unified IP & Telecomm Env -unite 3217/tcp # Unified IP & Telecomm Env -# Christer Gunnarsson -# -smartpackets 3218/udp # EMC SmartPackets -smartpackets 3218/tcp # EMC SmartPackets -# Steve Spataro -wms-messenger 3219/udp # WMS Messenger -wms-messenger 3219/tcp # WMS Messenger -# Michael Monasterio -xnm-ssl 3220/udp # XML NM over SSL -xnm-ssl 3220/tcp # XML NM over SSL -xnm-clear-text 3221/udp # XML NM over TCP -xnm-clear-text 3221/tcp # XML NM over TCP -# Mark Trostler -glbp 3222/udp # Gateway Load Balancing Pr -glbp 3222/tcp # Gateway Load Balancing Pr -# Douglas McLaggan -digivote 3223/udp # DIGIVOTE (R) Vote-Server -digivote 3223/tcp # DIGIVOTE (R) Vote-Server -# Christian Treczoks -aes-discovery 3224/udp # AES Discovery Port -aes-discovery 3224/tcp # AES Discovery Port -# Ken Richard -fcip-port 3225/udp # FCIP -fcip-port 3225/tcp # FCIP -# RFC-ietf-ips-fcovertcpip-12.txt -isi-irp 3226/udp # ISI Industry Software IRP -isi-irp 3226/tcp # ISI Industry Software IRP -# Peter Sandstrom -dwnmshttp 3227/udp # DiamondWave NMS Server -dwnmshttp 3227/tcp # DiamondWave NMS Server -dwmsgserver 3228/udp # DiamondWave MSG Server -dwmsgserver 3228/tcp # DiamondWave MSG Server -# Varma Bhupatiraju -global-cd-port 3229/udp # Global CD Port -global-cd-port 3229/tcp # Global CD Port -# Vitaly Revsin -sftdst-port 3230/udp # Software Distributor Port -sftdst-port 3230/tcp # Software Distributor Port -# Andrea Lanza -dsnl 3231/udp # Delta Solutions Direct -dsnl 3231/tcp # Delta Solutions Direct -# Peter Ijkhout -mdtp 3232/udp # MDT port -mdtp 3232/tcp # MDT port -# IJsbrand Wijnands -whisker 3233/udp # WhiskerControl main port -whisker 3233/tcp # WhiskerControl main port -# Rudolf Cardinal February 2002 -alchemy 3234/udp # Alchemy Server -alchemy 3234/tcp # Alchemy Server -# Mikhail Belov February 2002 -mdap-port 3235/udp # MDAP Port -mdap-port 3235/tcp # MDAP port -# Johan Deleu February 2002 -apparenet-ts 3236/udp # appareNet Test Server -apparenet-ts 3236/tcp # appareNet Test Server -apparenet-tps 3237/udp # appareNet Test Packet Sequencer -apparenet-tps 3237/tcp # appareNet Test Packet Sequencer -apparenet-as 3238/udp # appareNet Analysis Server -apparenet-as 3238/tcp # appareNet Analysis Server -apparenet-ui 3239/udp # appareNet User Interface -apparenet-ui 3239/tcp # appareNet User Interface -# Fred Klassen February 2002 -triomotion 3240/udp # Trio Motion Control Port -triomotion 3240/tcp # Trio Motion Control Port -# Tony Matthews February 2002 -sysorb 3241/udp # SysOrb Monitoring Server -sysorb 3241/tcp # SysOrb Monitoring Server -# Jakob Oestergaard February 2002 -sdp-id-port 3242/udp # Session Description ID -sdp-id-port 3242/tcp # Session Description ID -# Greg Rose February 2002 -timelot 3243/udp # Timelot Port -timelot 3243/tcp # Timelot Port -# David Ferguson February 2002 -onesaf 3244/udp # OneSAF -onesaf 3244/tcp # OneSAF -# Gene McCulley February 2002 -vieo-fe 3245/udp # VIEO Fabric Executive -vieo-fe 3245/tcp # VIEO Fabric Executive -# James Cox February 2002 -dvt-system 3246/udp # DVT SYSTEM PORT -dvt-system 3246/tcp # DVT SYSTEM PORT -dvt-data 3247/udp # DVT DATA LINK -dvt-data 3247/tcp # DVT DATA LINK -# Phillip Heil February 2002 -procos-lm 3248/udp # PROCOS LM -procos-lm 3248/tcp # PROCOS LM -# Torsten Rendelmann -# February 2002 -ssp 3249/udp # State Sync Protocol -ssp 3249/tcp # State Sync Protocol -# Stephane Beaulieu February 2002 -hicp 3250/udp # HMS hicp port -hicp 3250/tcp # HMS hicp port -# Joel Palsson, HMS Industrial Networks AB -# February 2002 -sysscanner 3251/udp # Sys Scanner -sysscanner 3251/tcp # Sys Scanner -# Dick Georges February 2002 -dhe 3252/udp # DHE port -dhe 3252/tcp # DHE port -# Fabrizio Massimo Ferrara February 2002 -pda-data 3253/udp # PDA Data -pda-data 3253/tcp # PDA Data -pda-sys 3254/udp # PDA System -pda-sys 3254/tcp # PDA System -# Jian Fan February 2002 -semaphore 3255/udp # Semaphore Connection Port -semaphore 3255/tcp # Semaphore Connection Port -# Jay Eckles February 2002 -cpqrpm-agent 3256/udp # Compaq RPM Agent Port -cpqrpm-agent 3256/tcp # Compaq RPM Agent Port -cpqrpm-server 3257/udp # Compaq RPM Server Port -cpqrpm-server 3257/tcp # Compaq RPM Server Port -# Royal King February 2002 -ivecon-port 3258/udp # Ivecon Server Port -ivecon-port 3258/tcp # Ivecon Server Port -# Serguei Tevs February 2002 -epncdp2 3259/udp # Epson Network Common Devi -epncdp2 3259/tcp # Epson Network Common Devi -# SEIKO EPSON Corporation - Oishi Toshiaki -# February 2002 -iscsi-target 3260/udp # iSCSI port -iscsi-target 3260/tcp # iSCSI port -# Julian Satran -winshadow 3261/udp # winShadow -winshadow 3261/tcp # winShadow -# Colin Barry -necp 3262/udp # NECP -necp 3262/tcp # NECP -# Alberto Cerpa -ecolor-imager 3263/udp # E-Color Enterprise Imager -ecolor-imager 3263/tcp # E-Color Enterprise Imager -# Tamara Baker -ccmail 3264/udp # cc:mail/lotus -ccmail 3264/tcp # cc:mail/lotus -# -altav-tunnel 3265/udp # Altav Tunnel -altav-tunnel 3265/tcp # Altav Tunnel -# Gary M. Allen -ns-cfg-server 3266/udp # NS CFG Server -ns-cfg-server 3266/tcp # NS CFG Server -# Aivi Lie -ibm-dial-out 3267/udp # IBM Dial Out -ibm-dial-out 3267/tcp # IBM Dial Out -# Skip Booth -msft-gc 3268/udp # Microsoft Global Catalog -msft-gc 3268/tcp # Microsoft Global Catalog -msft-gc-ssl 3269/udp # Microsoft Global Catalog with LDAP/SSL -msft-gc-ssl 3269/tcp # Microsoft Global Catalog with LDAP/SSL -# Asaf Kashi -verismart 3270/udp # Verismart -verismart 3270/tcp # Verismart -# Jay Weber -csoft-prev 3271/udp # CSoft Prev Port -csoft-prev 3271/tcp # CSoft Prev Port -# Nedelcho Stanev -user-manager 3272/udp # Fujitsu User Manager -user-manager 3272/tcp # Fujitsu User Manager -# Yukihiko Sakurai -sxmp 3273/udp # Simple Extensible Multiplexed Protocol -sxmp 3273/tcp # Simple Extensible Multiplexed Protocol -# Stuart Newman -ordinox-server 3274/udp # Ordinox Server -ordinox-server 3274/tcp # Ordinox Server -# Guy Letourneau -samd 3275/udp # SAMD -samd 3275/tcp # SAMD -# Edgar Circenis -maxim-asics 3276/udp # Maxim ASICs -maxim-asics 3276/tcp # Maxim ASICs -# Dave Inman -awg-proxy 3277/udp # AWG Proxy -awg-proxy 3277/tcp # AWG Proxy -# Alex McDonald -lkcmserver 3278/udp # LKCM Server -lkcmserver 3278/tcp # LKCM Server -# Javier Jimenez -admind 3279/udp # admind -admind 3279/tcp # admind -# Jeff Haynes -vs-server 3280/udp # VS Server -vs-server 3280/tcp # VS Server -# Scott Godlew -sysopt 3281/udp # SYSOPT -sysopt 3281/tcp # SYSOPT -# Tony Hoffman -datusorb 3282/udp # Datusorb -datusorb 3282/tcp # Datusorb -# Thomas Martin -net-assistant 3283/udp # Net Assistant -net-assistant 3283/tcp # Net Assistant -# Michael Stein -4talk 3284/udp # 4Talk -4talk 3284/tcp # 4Talk -# Tony Bushnell -plato 3285/udp # Plato -plato 3285/tcp # Plato -# Jim Battin -e-net 3286/udp # E-Net -e-net 3286/tcp # E-Net -# Steven Grigsby -directvdata 3287/udp # DIRECTVDATA -directvdata 3287/tcp # DIRECTVDATA -# Michael Friedman -cops 3288/udp # COPS -cops 3288/tcp # COPS -# Shai Herzog -enpc 3289/udp # ENPC -enpc 3289/tcp # ENPC -# SEIKO EPSON -caps-lm 3290/udp # CAPS LOGISTICS TOOLKIT - LM -caps-lm 3290/tcp # CAPS LOGISTICS TOOLKIT - LM -# Joseph Krebs -sah-lm 3291/udp # S A Holditch & Associates - LM -sah-lm 3291/tcp # S A Holditch & Associates - LM -# Randy Hudgens -cart-o-rama 3292/udp # Cart O Rama -cart-o-rama 3292/tcp # Cart O Rama -# Phillip Dillinger -fg-fps 3293/udp # fg-fps -fg-fps 3293/tcp # fg-fps -fg-gip 3294/udp # fg-gip -fg-gip 3294/tcp # fg-gip -# Jean-Marc Frailong -dyniplookup 3295/udp # Dynamic IP Lookup -dyniplookup 3295/tcp # Dynamic IP Lookup -# Eugene Osovetsky -rib-slm 3296/udp # Rib License Manager -rib-slm 3296/tcp # Rib License Manager -# Kristean Heisler -cytel-lm 3297/udp # Cytel License Manager -cytel-lm 3297/tcp # Cytel License Manager -# Yogesh P. Gajjar -deskview 3298/udp # DeskView -deskview 3298/tcp # DeskView -# Manfred Randelzofer -# -pdrncs 3299/udp # pdrncs -pdrncs 3299/tcp # pdrncs -# Paul Wissenbach -########### 3300-3301 Unauthorized Use by SAP R/3 ###### -mcs-fastmail 3302/udp # MCS Fastmail -mcs-fastmail 3302/tcp # MCS Fastmail -# Patti Jo Newsom -opsession-clnt 3303/udp # OP Session Client -opsession-clnt 3303/tcp # OP Session Client -opsession-srvr 3304/udp # OP Session Server -opsession-srvr 3304/tcp # OP Session Server -# Amir Blich -odette-ftp 3305/udp # ODETTE-FTP -odette-ftp 3305/tcp # ODETTE-FTP -# David Nash -mysql 3306/udp # MySQL -mysql 3306/tcp # MySQL -# Monty -opsession-prxy 3307/udp # OP Session Proxy -opsession-prxy 3307/tcp # OP Session Proxy -# Amir Blich -tns-server 3308/udp # TNS Server -tns-server 3308/tcp # TNS Server -tns-adv 3309/udp # TNS ADV -tns-adv 3309/tcp # TNS ADV -# Jerome Albin -dyna-access 3310/udp # Dyna Access -dyna-access 3310/tcp # Dyna Access -# Dave Belliveau -# -mcns-tel-ret 3311/udp # MCNS Tel Ret -mcns-tel-ret 3311/tcp # MCNS Tel Ret -# Randall Atkinson -appman-server 3312/udp # Application Management Server -appman-server 3312/tcp # Application Management Server -uorb 3313/udp # Unify Object Broker -uorb 3313/tcp # Unify Object Broker -uohost 3314/udp # Unify Object Host -uohost 3314/tcp # Unify Object Host -# Duane Gibson -cdid 3315/udp # CDID -cdid 3315/tcp # CDID -# Andrew Borisov -aicc-cmi 3316/udp # AICC/CMI -aicc-cmi 3316/tcp # AICC/CMI -# William McDonald -vsaiport 3317/udp # VSAI PORT -vsaiport 3317/tcp # VSAI PORT -# Rieko Asai -ssrip 3318/udp # Swith to Swith Routing Information Protocol -ssrip 3318/tcp # Swith to Swith Routing Information Protocol -# Baba Hidekazu -sdt-lmd 3319/udp # SDT License Manager -sdt-lmd 3319/tcp # SDT License Manager -# Salvo Nassisi -officelink2000 3320/udp # Office Link 2000 -officelink2000 3320/tcp # Office Link 2000 -# Mike Balch -vnsstr 3321/udp # VNSSTR -vnsstr 3321/tcp # VNSSTR -# Takeshi Ohmura -# Bob Braden -sftu 3326/udp # SFTU -sftu 3326/tcp # SFTU -# Eduardo Rosenberg de Moura -bbars 3327/udp # BBARS -bbars 3327/tcp # BBARS -# Lou Harris -egptlm 3328/udp # Eaglepoint License Manager -egptlm 3328/tcp # Eaglepoint License Manager -# Dave Benton -hp-device-disc 3329/udp # HP Device Disc -hp-device-disc 3329/tcp # HP Device Disc -# Shivaun Albright -mcs-calypsoicf 3330/udp # MCS Calypso ICF -mcs-calypsoicf 3330/tcp # MCS Calypso ICF -mcs-messaging 3331/udp # MCS Messaging -mcs-messaging 3331/tcp # MCS Messaging -mcs-mailsvr 3332/udp # MCS Mail Server -mcs-mailsvr 3332/tcp # MCS Mail Server -# Patti Jo Newsom -dec-notes 3333/udp # DEC Notes -dec-notes 3333/tcp # DEC Notes -# Kim Moraros -directv-web 3334/udp # Direct TV Webcasting -directv-web 3334/tcp # Direct TV Webcasting -directv-soft 3335/udp # Direct TV Software Updates -directv-soft 3335/tcp # Direct TV Software Updates -directv-tick 3336/udp # Direct TV Tickers -directv-tick 3336/tcp # Direct TV Tickers -directv-catlg 3337/udp # Direct TV Data Catalog -directv-catlg 3337/tcp # Direct TV Data Catalog -# Michael Friedman -anet-b 3338/udp # OMF data b -anet-b 3338/tcp # OMF data b -anet-l 3339/udp # OMF data l -anet-l 3339/tcp # OMF data l -anet-m 3340/udp # OMF data m -anet-m 3340/tcp # OMF data m -anet-h 3341/udp # OMF data h -anet-h 3341/tcp # OMF data h -# Per Sahlqvist -webtie 3342/udp # WebTIE -webtie 3342/tcp # WebTIE -# Kevin Frender -ms-cluster-net 3343/udp # MS Cluster Net -ms-cluster-net 3343/tcp # MS Cluster Net -# Mike Massa -bnt-manager 3344/udp # BNT Manager -bnt-manager 3344/tcp # BNT Manager -# Brian J. Ives -influence 3345/udp # Influence -influence 3345/tcp # Influence -# Russ Ferriday -trnsprntproxy 3346/udp # Trnsprnt Proxy -trnsprntproxy 3346/tcp # Trnsprnt Proxy -# Grant Kirby -phoenix-rpc 3347/udp # Phoenix RPC -phoenix-rpc 3347/tcp # Phoenix RPC -# Ian Anderson -pangolin-laser 3348/udp # Pangolin Laser -pangolin-laser 3348/tcp # Pangolin Laser -# William Benner -chevinservices 3349/udp # Chevin Services -chevinservices 3349/tcp # Chevin Services -# Gus McNaughton -findviatv 3350/udp # FINDVIATV -findviatv 3350/tcp # FINDVIATV -# Oran Davis -btrieve 3351/udp # Btrieve port -btrieve 3351/tcp # Btrieve port -ssql 3352/udp # Scalable SQL -ssql 3352/tcp # Scalable SQL -# Chuck Talk -fatpipe 3353/udp # FATPIPE -fatpipe 3353/tcp # FATPIPE -# Sanchaita Datta -suitjd 3354/udp # SUITJD -suitjd 3354/tcp # SUITJD -# Todd Moyer -ordinox-dbase 3355/udp # Ordinox Dbase -ordinox-dbase 3355/tcp # Ordinox Dbase -# Guy Litourneau -upnotifyps 3356/udp # UPNOTIFYPS -upnotifyps 3356/tcp # UPNOTIFYPS -# Mark Fox -adtech-test 3357/udp # Adtech Test IP -adtech-test 3357/tcp # Adtech Test IP -# Robin Uyeshiro -mpsysrmsvr 3358/udp # Mp Sys Rmsvr -mpsysrmsvr 3358/tcp # Mp Sys Rmsvr -# Hiroyuki Kawabuchi -wg-netforce 3359/udp # WG NetForce -wg-netforce 3359/tcp # WG NetForce -# Lee Wheat -kv-server 3360/udp # KV Server -kv-server 3360/tcp # KV Server -kv-agent 3361/udp # KV Agent -kv-agent 3361/tcp # KV Agent -# Thomas Soranno -dj-ilm 3362/udp # DJ ILM -dj-ilm 3362/tcp # DJ ILM -# Don Tyson -nati-vi-server 3363/udp # NATI Vi Server -nati-vi-server 3363/tcp # NATI Vi Server -# Robert Dye -creativeserver 3364/udp # Creative Server -creativeserver 3364/tcp # Creative Server -contentserver 3365/udp # Content Server -contentserver 3365/tcp # Content Server -creativepartnr 3366/udp # Creative Partner -creativepartnr 3366/tcp # Creative Partner -# Jesus Ortiz -# Scott Engel -tip2 3372/udp # TIP 2 -tip2 3372/tcp # TIP 2 -# Keith Evans -lavenir-lm 3373/udp # Lavenir License Manager -lavenir-lm 3373/tcp # Lavenir License Manager -# Marius Matioc -cluster-disc 3374/udp # Cluster Disc -cluster-disc 3374/tcp # Cluster Disc -# Jeff Hughes -vsnm-agent 3375/udp # VSNM Agent -vsnm-agent 3375/tcp # VSNM Agent -# Venkat Rangan -cdbroker 3376/udp # CD Broker -cdbroker 3376/tcp # CD Broker -# Moon Ho Chung -cogsys-lm 3377/udp # Cogsys Network License Manager -cogsys-lm 3377/tcp # Cogsys Network License Manager -# Simon Chinnick -wsicopy 3378/udp # WSICOPY -wsicopy 3378/tcp # WSICOPY -# James Overby -socorfs 3379/udp # SOCORFS -socorfs 3379/tcp # SOCORFS -# Hugo Charbonneau -sns-channels 3380/udp # SNS Channels -sns-channels 3380/tcp # SNS Channels -# Shekar Pasumarthi -geneous 3381/udp # Geneous -geneous 3381/tcp # Geneous -# Nick de Smith -fujitsu-neat 3382/udp # Fujitsu Network Enhanced Antitheft function -fujitsu-neat 3382/tcp # Fujitsu Network Enhanced Antitheft function -# Markku Viima -esp-lm 3383/udp # Enterprise Software Products License Manager -esp-lm 3383/tcp # Enterprise Software Products License Manager -# George Rudy -hp-clic 3384/udp # Hardware Management -hp-clic 3384/tcp # Cluster Management Services -# Rajesh Srinivasaraghavan -qnxnetman 3385/udp # qnxnetman -qnxnetman 3385/tcp # qnxnetman -# Michael Hunter -gprs-sig 3386/udp # GPRS SIG -gprs-data 3386/tcp # GPRS Data -# Ansgar Bergmann -backroomnet 3387/udp # Back Room Net -backroomnet 3387/tcp # Back Room Net -# Clayton Wilkinson -cbserver 3388/udp # CB Server -cbserver 3388/tcp # CB Server -# Allen Wei -ms-wbt-server 3389/udp # MS WBT Server -ms-wbt-server 3389/tcp # MS WBT Server -# Ritu Bahl -dsc 3390/udp # Distributed Service Coordinator -dsc 3390/tcp # Distributed Service Coordinator -# Chas Honton -savant 3391/udp # SAVANT -savant 3391/tcp # SAVANT -# Andy Bruce -efi-lm 3392/udp # EFI License Management -efi-lm 3392/tcp # EFI License Management -# Ross E. Greinke -d2k-tapestry1 3393/udp # D2K Tapestry Client to Server -d2k-tapestry1 3393/tcp # D2K Tapestry Client to Server -d2k-tapestry2 3394/udp # D2K Tapestry Server to Server -d2k-tapestry2 3394/tcp # D2K Tapestry Server to Server -# Eric Lan -dyna-lm 3395/udp # Dyna License Manager (Elam) -dyna-lm 3395/tcp # Dyna License Manager (Elam) -# Anjana Iyer -printer_agent 3396/udp # Printer Agent -printer_agent 3396/tcp # Printer Agent -# Devon Taylor -cloanto-lm 3397/udp # Cloanto License Manager -cloanto-lm 3397/tcp # Cloanto License Manager -# Takeo Sato -mercantile 3398/udp # Mercantile -mercantile 3398/tcp # Mercantile -# Erik Kragh Jensen -csms 3399/udp # CSMS -csms 3399/tcp # CSMS -csms2 3400/udp # CSMS2 -csms2 3400/tcp # CSMS2 -# Markus Michels -filecast 3401/udp # filecast -filecast 3401/tcp # filecast -# Eden Sherry -fxaengine-net 3402/udp # FXa Engine Network Port -fxaengine-net 3402/tcp # FXa Engine Network Port -# Lucas Alonso February 2002 -copysnap 3403/udp # CopySnap Server Port -copysnap 3403/tcp # CopySnap Server Port -# Steve Zellers February 2002 -# 3404 Removed (2002-05-01) -nokia-ann-ch1 3405/udp # Nokia Announcement ch 1 -nokia-ann-ch1 3405/tcp # Nokia Announcement ch 1 -nokia-ann-ch2 3406/udp # Nokia Announcement ch 2 -nokia-ann-ch2 3406/tcp # Nokia Announcement ch 2 -# Morteza Kalhour February 2002 -ldap-admin 3407/udp # LDAP admin server port -ldap-admin 3407/tcp # LDAP admin server port -# Stephen Tsun February 2002 -issapi 3408/udp # POWERpack API Port -issapi 3408/tcp # POWERpack API Port -# Colin Griffiths February 2002 -networklens 3409/udp # NetworkLens Event Port -networklens 3409/tcp # NetworkLens Event Port -networklenss 3410/udp # NetworkLens SSL Event -networklenss 3410/tcp # NetworkLens SSL Event -# Greg Bailey February 2002 -biolink-auth 3411/udp # BioLink Authenteon server -biolink-auth 3411/tcp # BioLink Authenteon server -# BioLink Support February 2002 -xmlblaster 3412/udp # xmlBlaster -xmlblaster 3412/tcp # xmlBlaster -# Marcel Ruff February 2002 -svnet 3413/udp # SpecView Networking -svnet 3413/tcp # SpecView Networking -# Richard Dickins February 2002 -wip-port 3414/udp # BroadCloud WIP Port -wip-port 3414/tcp # BroadCloud WIP Port -bcinameservice 3415/udp # BCI Name Service -bcinameservice 3415/tcp # BCI Name Service -# Dennis Parker February 2002 -commandport 3416/udp # AirMobile IS Command Port -commandport 3416/tcp # AirMobile IS Command Port -# Mike Klein February 2002 -csvr 3417/udp # ConServR file translation -csvr 3417/tcp # ConServR file translation -# Albert Leung February 2002 -rnmap 3418/udp # Remote nmap -rnmap 3418/tcp # Remote nmap -# Tuomo Makinen February 2002 -softaudit 3419/udp # ISogon SoftAudit -softaudit 3419/tcp # Isogon SoftAudit -# Per Hellberg February 2002 -ifcp-port 3420/udp # iFCP User Port -ifcp-port 3420/tcp # iFCP User Port -# Charles Monia -bmap 3421/udp # Bull Apprise portmapper -bmap 3421/tcp # Bull Apprise portmapper -# Jeremy Gilbert -rusb-sys-port 3422/udp # Remote USB System Port -rusb-sys-port 3422/tcp # Remote USB System Port -# Steven Klein February 2002 -xtrm 3423/udp # xTrade Reliable Messaging -xtrm 3423/tcp # xTrade Reliable Messaging -xtrms 3424/udp # xTrade over TLS/SSL -xtrms 3424/tcp # xTrade over TLS/SSL -# Mats Nilsson February 2002 -agps-port 3425/udp # AGPS Access Port -agps-port 3425/tcp # AGPS Access Port -# Kristoffer Nilsson -# February 2002 -arkivio 3426/udp # Arkivio Storage Protocol -arkivio 3426/tcp # Arkivio Storage Protocol -# Bruce Greenblatt February 2002 -websphere-snmp 3427/udp # WebSphere SNMP -websphere-snmp 3427/tcp # WebSphere SNMP -# Richard Mills February 2002 -twcss 3428/udp # 2Wire CSS -twcss 3428/tcp # 2Wire CSS -# 2Wire IANA Contact February 2002 -gcsp 3429/udp # GCSP user port -gcsp 3429/tcp # GCSP user port -# Anirban Majumder March 2002 -ssdispatch 3430/udp # Scott Studios Dispatch -ssdispatch 3430/tcp # Scott Studios Dispatch -# Michael Settles March 2002 -ndl-als 3431/udp # Active License Server Port -ndl-als 3431/tcp # Active License Server Port -# Quentin Brown March 2002 -osdcp 3432/udp # Secure Device Protocol -osdcp 3432/tcp # Secure Device Protocol -# Peter Fernandez March 2002 -alta-smp 3433/udp # Altaworks Service Management Platform -alta-smp 3433/tcp # Altaworks Service Management Platform -# Ted Macomber March 2002 -opencm 3434/udp # OpenCM Server -opencm 3434/tcp # OpenCM Server -# Jonathan S. Shapiro March 2002 -pacom 3435/udp # Pacom Security User Port -pacom 3435/tcp # Pacom Security User Port -# Steve Barton March 2002 -gc-config 3436/udp # GuardControl Exchange Protocol -gc-config 3436/tcp # GuardControl Exchange Protocol -# Andreas Schwarz March 2002 -autocueds 3437/udp # Autocue Directory Service -autocueds 3437/tcp # Autocue Directory Service -# Geoff Back March 2002 -spiral-admin 3438/udp # Spiralcraft Admin -spiral-admin 3438/tcp # Spiralcraft Admin -# Michael Toth March 2002 -hri-port 3439/udp # HRI Interface Port -hri-port 3439/tcp # HRI Interface Port -# John Fayos March 2002 -ans-console 3440/udp # Net Steward Mgmt Console -ans-console 3440/tcp # Net Steward Mgmt Console -# John Richmond March 2002 -connect-client 3441/udp # OC Connect Client -connect-client 3441/tcp # OC Connect Client -connect-server 3442/udp # OC Connect Server -connect-server 3442/tcp # OC Connect Server -# Mike Velten March 2002 -ov-nnm-websrv 3443/udp # OpenView Network Node Manager WEB Server -ov-nnm-websrv 3443/tcp # OpenView Network Node Manager WEB Server -# Anthony Walker March 2002 -denali-server 3444/udp # Denali Server -denali-server 3444/tcp # Denali Server -# Joe Devlin March 2002 -monp 3445/udp # Media Object Network -monp 3445/tcp # Media Object Network -# Ron Herardian March 2002 -3comfaxrpc 3446/udp # 3Com FAX RPC port -3comfaxrpc 3446/tcp # 3Com FAX RPC port -# Christopher Wells April 2002 -cddn 3447/udp # CompuDuo DirectNet -cddn 3447/tcp # CompuDuo DirectNet -# Gregory Richards April 2002 -dnc-port 3448/udp # Discovery and Net Config -dnc-port 3448/tcp # Discovery and Net Config -# Chi Chen April 2002 -hotu-chat 3449/udp # HotU Chat -hotu-chat 3449/tcp # HotU Chat -# Tim Burgess April 2002 -castorproxy 3450/udp # CAStorProxy -castorproxy 3450/tcp # CAStorProxy -# Raymond J. Young April 2002 -asam 3451/udp # ASAM Services -asam 3451/tcp # ASAM Services -# Mike Gossett April 2002 -sabp-signal 3452/udp # SABP-Signalling Protocol -sabp-signal 3452/tcp # SABP-Signalling Protocol -# Brendan McWilliams April 2002 -pscupd 3453/udp # PSC Update Port -pscupd 3453/tcp # PSC Update Port -# Reid B. Ligon -mira 3454/tcp # Apple Remote Access Protocol -# Mike Alexander -prsvp 3455/udp # RSVP Port -prsvp 3455/tcp # RSVP Port -# Bob Braden -vat 3456/udp # VAT default data -vat 3456/tcp # VAT default data -# Van Jacobson -vat-control 3457/udp # VAT default control -vat-control 3457/tcp # VAT default control -# Van Jacobson -d3winosfi 3458/udp # D3WinOSFI -d3winosfi 3458/tcp # D3WinOSFI -# Brad Hamilton -integral 3459/udp # TIP Integral -integral 3459/tcp # TIP Integral -# Olivier Mascia -edm-manager 3460/udp # EDM Manger -edm-manager 3460/tcp # EDM Manger -edm-stager 3461/udp # EDM Stager -edm-stager 3461/tcp # EDM Stager -edm-std-notify 3462/udp # EDM STD Notify -edm-std-notify 3462/tcp # EDM STD Notify -edm-adm-notify 3463/udp # EDM ADM Notify -edm-adm-notify 3463/tcp # EDM ADM Notify -edm-mgr-sync 3464/udp # EDM MGR Sync -edm-mgr-sync 3464/tcp # EDM MGR Sync -edm-mgr-cntrl 3465/udp # EDM MGR Cntrl -edm-mgr-cntrl 3465/tcp # EDM MGR Cntrl -# Tom Hennessy -workflow 3466/udp # WORKFLOW -workflow 3466/tcp # WORKFLOW -# Robert Hufsky -rcst 3467/udp # RCST -rcst 3467/tcp # RCST -# Kit Sturgeon -ttcmremotectrl 3468/udp # TTCM Remote Controll -ttcmremotectrl 3468/tcp # TTCM Remote Controll -# Yossi Cohen-Shahar -pluribus 3469/udp # Pluribus -pluribus 3469/tcp # Pluribus -# Mark Miller -jt400 3470/udp # jt400 -jt400 3470/tcp # jt400 -jt400-ssl 3471/udp # jt400-ssl -jt400-ssl 3471/tcp # jt400-ssl -# Clifton Nock -jaugsremotec-1 3472/udp # JAUGS N-G Remotec 1 -jaugsremotec-1 3472/tcp # JAUGS N-G Remotec 1 -jaugsremotec-2 3473/udp # JAUGS N-G Remotec 2 -jaugsremotec-2 3473/tcp # JAUGS N-G Remotec 2 -# Steven B. Cliff April 2002 -ttntspauto 3474/udp # TSP Automation -ttntspauto 3474/tcp # TSP Automation -# Arnie Koster April 2002 -genisar-port 3475/udp # Genisar Comm Port -genisar-port 3475/tcp # Genisar Comm Port -# Candace Niccolson April 2002 -nppmp 3476/udp # NVIDIA Mgmt Protocol -nppmp 3476/tcp # NVIDIA Mgmt Protocol -# Gilbert Yeung April 2002 -ecomm 3477/udp # eComm link port -ecomm 3477/tcp # eComm link port -# Thomas Soerensen April 2002 -nat-stun-port 3478/udp # Simple Traversal of UDP Through NAT (STUN) port -nat-stun-port 3478/tcp # Simple Traversal of UDP Through NAT (STUN) port -# Jonathan Rosenberg April 2002 -twrpc 3479/udp # 2Wire RPC -twrpc 3479/tcp # 2Wire RPC -# 2Wire IANA Contact April 2002 -plethora 3480/udp # Secure Virtual Workspace -plethora 3480/tcp # Secure Virtual Workspace -# Tim Simms April 2002 -cleanerliverc 3481/udp # CleanerLive remote ctrl -cleanerliverc 3481/tcp # CleanerLive remote ctrl -# David Mojdehi April 2002 -vulture 3482/udp # Vulture Monitoring System -vulture 3482/tcp # Vulture Monitoring System -# Jason Santos April 2002 -slim-devices 3483/udp # Slim Devices Protocol -slim-devices 3483/tcp # Slim Devices Protocol -# Sean Adams May 2002 -gbs-stp 3484/udp # GBS SnapTalk Protocol -gbs-stp 3484/tcp # GBS SnapTalk Protocol -# Eric Harris-Braun May 2002 -celatalk 3485/udp # CelaTalk -celatalk 3485/tcp # CelaTalk -# Carl Blundell May 2002 -ifsf-hb-port 3486/udp # IFSF Heartbeat Port -ifsf-hb-port 3486/tcp # IFSF Heartbeat Port -# IFSF Secretary May 2002 -ltcudp 3487/udp # LISA UDP Transfer Channel -ltctcp 3487/tcp # LISA TCP Transfer Channel -# Pit Vetterick May 2002 -fs-rh-srv 3488/udp # FS Remote Host Server -fs-rh-srv 3488/tcp # FS Remote Host Server -# Brian Nickles May 2002 -dtp-dia 3489/udp # DTP/DIA -dtp-dia 3489/tcp # DTP/DIA -# Alexei V. Soloviev May 2002 -colubris 3490/udp # Colubris Management Port -colubris 3490/tcp # Colubris Management Port -# Gilbert Moineau May 2002 -swr-port 3491/udp # SWR Port -swr-port 3491/tcp # SWR Port -# Ian Manning May 2002 -tvdumtray-port 3492/udp # TVDUM Tray Port -tvdumtray-port 3492/tcp # TVDUM Tray Port -# Peter Boers May 2002 -nut 3493/udp # Network UPS Tools -nut 3493/tcp # Network UPS Tools -# Russell Kroll May 2002 -ibm3494 3494/udp # IBM 3494 -ibm3494 3494/tcp # IBM 3494 -# Jeffrey Pilch -seclayer-tcp 3495/udp # securitylayer over tcp -seclayer-tcp 3495/tcp # securitylayer over tcp -seclayer-tls 3496/udp # securitylayer over tls -seclayer-tls 3496/tcp # securitylayer over tls -# Arno Hollosi March 2002 -ipether232port 3497/udp # ipEther232Port -ipether232port 3497/tcp # ipEther232Port -# Marcus Leufgen May 2002 -dashpas-port 3498/udp # DASHPAS user port -dashpas-port 3498/tcp # DASHPAS user port -# Albrecht Mayer May 2002 -sccip-media 3499/udp # SccIP Media -sccip-media 3499/tcp # SccIP Media -# David Yon May 2002 -rtmp-port 3500/udp # RTMP Port -rtmp-port 3500/tcp # RTMP Port -# Miriam Wohlgelernter -isoft-p2p 3501/udp # iSoft-P2P -isoft-p2p 3501/tcp # iSoft-P2P -# David Walling -avinstalldisc 3502/udp # Avocent Install Discovery -avinstalldisc 3502/tcp # Avocent Install Discovery -# Brian S. Stewart -lsp-ping 3503/udp # MPLS LSP-echo Port -lsp-ping 3503/tcp # MPLS LSP-echo Port -# Ping Pan -ironstorm 3504/udp # IronStorm game server -ironstorm 3504/tcp # IronStorm game server -# Arnaud Clermonte -ccmcomm 3505/udp # CCM communications port -ccmcomm 3505/tcp # CCM communications port -# Tom Bougan -apc-3506 3506/udp # APC 3506 -apc-3506 3506/tcp # APC 3506 -# American Power Conversion -nesh-broker 3507/udp # Nesh Broker Port -nesh-broker 3507/tcp # Nesh Broker Port -# Jeremy Maiden -interactionweb 3508/udp # Interaction Web -interactionweb 3508/tcp # Interaction Web -# Andy Niksch -vt-ssl 3509/udp # Virtual Token SSL Port -vt-ssl 3509/tcp # Virtual Token SSL Port -# Libor Sykora May 2002 -xss-port 3510/udp # XSS Port -xss-port 3510/tcp # XSS Port -# Joe Purcell May 2002 -webmail-2 3511/udp # WebMail/2 -webmail-2 3511/tcp # WebMail/2 -# Dimitris Michelinakis May 2002 -aztec 3512/udp # Aztec Distribution Port -aztec 3512/tcp # Aztec Distribution Port -# Alan Francis May 2002 -arcpd 3513/udp # Adaptec Remote Protocol -arcpd 3513/tcp # Adaptec Remote Protocol -# Hardy Doelfel May 2002 -must-p2p 3514/udp # MUST Peer to Peer -must-p2p 3514/tcp # MUST Peer to Peer -must-backplane 3515/udp # MUST Backplane -must-backplane 3515/tcp # MUST Backplane -# Rick Stefanik May 2002 -smartcard-port 3516/udp # Smartcard Port -smartcard-port 3516/tcp # Smartcard Port -# Scott Guthery May 2002 -802-11-iapp 3517/udp # IEEE 802.11 WLANs WG IAPP -802-11-iapp 3517/tcp # IEEE 802.11 WLANs WG IAPP -# Stuart J. Kerry (Chair IEEE 802.11 WG) -# May 2002 -artifact-msg 3518/udp # Artifact Message Server -artifact-msg 3518/tcp # Artifact Message Server -# Ron Capwell June 2002 -galileo 3519/udp # Netvion Galileo Port -nvmsgd 3519/tcp # Netvion Messenger Port -galileolog 3520/udp # Netvion Galileo Log Port -galileolog 3520/tcp # Netvion Galileo Log Port -# Ray Caruso June 2002 -mc3ss 3521/udp # Telequip Labs MC3SS -mc3ss 3521/tcp # Telequip Labs MC3SS -# Michael Sparks June 2002 -nssocketport 3522/udp # DO over NSSocketPort -nssocketport 3522/tcp # DO over NSSocketPort -# Douglas Davidson June 2002 -odeumservlink 3523/udp # Odeum Serverlink -odeumservlink 3523/tcp # Odeum Serverlink -# Mads Peter Back June 2002 -ecmport 3524/udp # ECM Server port -ecmport 3524/tcp # ECM Server port -eisport 3525/udp # EIS Server port -eisport 3525/tcp # EIS Server port -# Paul Kraus June 2002 -starquiz-port 3526/udp # starQuiz Port -starquiz-port 3526/tcp # starQuiz Port -# Adam Ernst June 2002 -beserver-msg-q 3527/udp # VERITAS Backup Exec Server -beserver-msg-q 3527/tcp # VERITAS Backup Exec Server -# Katherine Wattwood June 2002 -jboss-iiop 3528/udp # JBoss IIOP -jboss-iiop 3528/tcp # JBoss IIOP -jboss-iiop-ssl 3529/udp # JBoss IIOP/SSL -jboss-iiop-ssl 3529/tcp # JBoss IIOP/SSL -# Francisco Reverbel June 2002 -gf 3530/udp # Grid Friendly -gf 3530/tcp # Grid Friendly -# Daivd P. Chassin June 2002 -joltid 3531/udp # Joltid -joltid 3531/tcp # Joltid -# Ahti Heinla June 2002 -raven-rmp 3532/udp # Raven Remote Management Control -raven-rmp 3532/tcp # Raven Remote Management Control -raven-rdp 3533/udp # Raven Remote Management Data -raven-rdp 3533/tcp # Raven Remote Management Data -# Daniel Sorlov June 2002 -urld-port 3534/udp # URL Daemon Port -urld-port 3534/tcp # URL Daemon Port -# Jim Binkley June 2002 -ms-la 3535/udp # MS-LA -ms-la 3535/tcp # MS-LA -# Eric Ledoux -snac 3536/udp # SNAC -snac 3536/tcp # SNAC -# Tatsuya Igarashi July 2002 -ni-visa-remote 3537/udp # Remote NI-VISA port -ni-visa-remote 3537/tcp # Remote NI-VISA port -# Sinnadurai Dharshan July 2002 -ibm-diradm 3538/udp # IBM Directory Server -ibm-diradm 3538/tcp # IBM Directory Server -ibm-diradm-ssl 3539/udp # IBM Directory Server SSL -ibm-diradm-ssl 3539/tcp # IBM Directory Server SSL -# Mark Cavage July 2002 -pnrp-port 3540/udp # PNRP User Port -pnrp-port 3540/tcp # PNRP User Port -# Igor Kostic July 2002 -voispeed-port 3541/udp # VoiSpeed Port -voispeed-port 3541/tcp # VoiSpeed Port -# Virgilio Lattanzi July 2002 -hacl-monitor 3542/udp # HA cluster monitor -hacl-monitor 3542/tcp # HA cluster monitor -# Jason Ko July 2002 -qftest-lookup 3543/udp # qftest Lookup Port -qftest-lookup 3543/tcp # qftest Lookup Port -# Gregor Schmid July 2002 -teredo 3544/udp # Teredo Port -teredo 3544/tcp # Teredo Port -# Dave Thaler July 2002 -camac 3545/udp # CAMAC equipment -camac 3545/tcp # CAMAC equipment -# Eugene Zhiganov July 2002 -# 3546 Unassigned (removed September 2002) -symantec-sim 3547/udp # Symantec SIM -symantec-sim 3547/tcp # Symantec SIM -# George Dzieciol July 2002 -interworld 3548/udp # Interworld -interworld 3548/tcp # Interworld -# John Stephen July 2002 -tellumat-nms 3549/udp # Tellumat MDR NMS -tellumat-nms 3549/tcp # Tellumat MDR NMS -# Hennie van der Merwe July 2002 -ssmpp 3550/udp # Secure SMPP -ssmpp 3550/tcp # Secure SMPP -# Cormac Long July 2002 -apcupsd 3551/udp # Apcupsd Information Port -apcupsd 3551/tcp # Apcupsd Information Port -# Riccardo Facchetti July 2002 -taserver 3552/udp # TeamAgenda Server Port -taserver 3552/tcp # TeamAgenda Server Port -# Dany Ayotte July 2002 -rbr-discovery 3553/udp # Red Box Recorder ADP -rbr-discovery 3553/tcp # Red Box Recorder ADP -# Simon Jolly July 2002 -questnotify 3554/udp # Quest Notification Server -questnotify 3554/tcp # Quest Notification Server -# Rob Griffin July 2002 -razor 3555/udp # Vipul's Razor -razor 3555/tcp # Vipul's Razor -# Vipul Ved Prakash July 2002 -sky-transport 3556/udp # Sky Transport Protocol -sky-transport 3556/tcp # Sky Transport Protocol -# Michael Paddon July 2002 -personalos-001 3557/udp # PersonalOS Comm Port -personalos-001 3557/tcp # PersonalOS Comm Port -# Shane Roberts July 2002 -mcp-port 3558/udp # MCP user port -mcp-port 3558/tcp # MCP user port -# Professor Paul S. Wang July 2002 -cctv-port 3559/udp # CCTV control port -cctv-port 3559/tcp # CCTV control port -# Raymond Lyons July 2002 -iniserve-port 3560/udp # INIServe port -iniserve-port 3560/tcp # INIServe port -# Peter Moylan August 2002 -bmc-onekey 3561/udp # BMC-OneKey -bmc-onekey 3561/tcp # BMC-OneKey -# Alon Tam August 2002 -sdbproxy 3562/udp # SDBProxy -sdbproxy 3562/tcp # SDBProxy -# Eric Grange August 2002 -watcomdebug 3563/udp # Watcom Debug -watcomdebug 3563/tcp # Watcom Debug -# Dave Neudoerffer -esimport 3564/udp # Electromed SIM port -esimport 3564/tcp # Electromed SIM port -# Francois Marchand August 2002 -m2pa 3565/sctp # M2PA -m2pa 3565/tcp # M2PA -# Tom George May 2002 -quest-launcher 3566/udp # Quest Agent Manager -quest-launcher 3566/tcp # Quest Agent Manager -# Eyal Kalderon April 2002 -emware-oft 3567/udp # emWare OFT Services -emware-oft 3567/tcp # emWare OFT Services -# Bryant Eastham August 2002 -emware-epss 3568/udp # emWare EMIT/Secure -emware-epss 3568/tcp # emWare EMIT/Secure -# Bryant Eastham January 2003 -mbg-ctrl 3569/udp # Meinberg Control Service -mbg-ctrl 3569/tcp # Meinberg Control Service -# Martin Burnicki August 2002 -mccwebsvr-port 3570/udp # MCC Web Server Port -mccwebsvr-port 3570/tcp # MCC Web Server Port -megardsvr-port 3571/udp # MegaRAID Server Port -megardsvr-port 3571/tcp # MegaRAID Server Port -megaregsvrport 3572/udp # Registration Server Port -megaregsvrport 3572/tcp # Registration Server Port -# Sreenivas Bagalkote August 2002 -tag-ups-1 3573/udp # Advantage Group UPS Suite -tag-ups-1 3573/tcp # Advantage Group UPS Suite -# James Goddard August 2002 -dmaf-caster 3574/udp # DMAF Caster -dmaf-server 3574/tcp # DMAF Server -# Ramakrishna Nadendla August 2002 -ccm-port 3575/udp # Coalsere CCM Port -ccm-port 3575/tcp # Coalsere CCM Port -cmc-port 3576/udp # Coalsere CMC Port -cmc-port 3576/tcp # Coalsere CMC Port -# Chris Hawkinson August 2002 -config-port 3577/udp # Configuration Port -config-port 3577/tcp # Configuration Port -data-port 3578/udp # Data Port -data-port 3578/tcp # Data Port -# Anupam Bharali August 2002 -ttat3lb 3579/udp # Tarantella Load Balancing -ttat3lb 3579/tcp # Tarantella Load Balancing -# Jim Musgrave August 2002 -nati-svrloc 3580/udp # NATI-ServiceLocator -nati-svrloc 3580/tcp # NATI-ServiceLocator -# Jason Case August 2002 -kfxaclicensing 3581/udp # Ascent Capture Licensing -kfxaclicensing 3581/tcp # Ascent Capture Licensing -# Brad Hamilton August 2002 -press 3582/udp # PEG PRESS Server -press 3582/tcp # PEG PRESS Server -# Jim DeLisle August 2002 -canex-watch 3583/udp # CANEX Watch System -canex-watch 3583/tcp # CANEX Watch System -# Peter Kollath August 2002 -u-dbap 3584/udp # U-DBase Access Protocol -u-dbap 3584/tcp # U-DBase Access Protocol -# Bodo Rueskamp August 2002 -emprise-lls 3585/udp # Emprise License Server -emprise-lls 3585/tcp # Emprise License Server -emprise-lsc 3586/udp # License Server Console -emprise-lsc 3586/tcp # License Server Console -# James J. Diaz August 2002 -p2pgroup 3587/udp # Peer to Peer Grouping -p2pgroup 3587/tcp # Peer to Peer Grouping -# Igor Kostic August 2002 -sentinel 3588/udp # Sentinel Server -sentinel 3588/tcp # Sentinel Server -# Ian Gordon August 2002 -isomair 3589/udp # isomair -isomair 3589/tcp # isomair -# Richard Fleming August 2002 -wv-csp-sms 3590/udp # WV CSP SMS Binding -wv-csp-sms 3590/tcp # WV CSP SMS Binding -# Matti Salmi August 2002 -gtrack-server 3591/udp # LOCANIS G-TRACK Server -gtrack-server 3591/tcp # LOCANIS G-TRACK Server -gtrack-ne 3592/udp # LOCANIS G-TRACK NE Port -gtrack-ne 3592/tcp # LOCANIS G-TRACK NE Port -# Juergen.Edelhaeuser August 2002 -bpmd 3593/udp # BP Model Debugger -bpmd 3593/tcp # BP Model Debugger -# Keith Fligg September 2002 -mediaspace 3594/udp # MediaSpace -mediaspace 3594/tcp # MediaSpace -shareapp 3595/udp # ShareApp -shareapp 3595/tcp # ShareApp -# Jeff King September 2002 -iw-mmogame 3596/udp # Illusion Wireless MMOG -iw-mmogame 3596/tcp # Illusion Wireless MMOG -# Jan Vrsinsky September 2002 -a14 3597/udp # A14 (AN-to-SC/MM) -a14 3597/tcp # A14 (AN-to-SC/MM) -a15 3598/udp # A15 (AN-to-AN) -a15 3598/tcp # A15 (AN-to-AN) -# David Ott September 2002 -quasar-server 3599/udp # Quasar Accounting Server -quasar-server 3599/tcp # Quasar Accounting Server -# Brad Pepers September 2002 -trap-daemon 3600/udp # text relay-answer -trap-daemon 3600/tcp # text relay-answer -# John Willis September 2002 -visinet-gui 3601/udp # Visinet Gui -visinet-gui 3601/tcp # Visinet Gui -# Jeff Douglass September 2002 -infiniswitchcl 3602/udp # InfiniSwitch Mgr Client -infiniswitchcl 3602/tcp # InfiniSwitch Mgr Client -# Lee VanTine September 2002 -int-rcv-cntrl 3603/udp # Integrated Rcvr Control -int-rcv-cntrl 3603/tcp # Integrated Rcvr Control -# Dave Stone September 2002 -bmc-jmx-port 3604/udp # BMC JMX Port -bmc-jmx-port 3604/tcp # BMC JMX Port -# Mike Behne September 2002 -comcam-io 3605/udp # ComCam IO Port -comcam-io 3605/tcp # ComCam IO Port -# Don Gilbreath September 2002 -splitlock 3606/udp # Splitlock Server -splitlock 3606/tcp # Splitlock Server -# Andrew Tune September 2002 -precise-i3 3607/udp # Precise I3 -precise-i3 3607/tcp # Precise I3 -# Tomer Shain September 2002 -trendchip-dcp 3608/udp # Trendchip control protocol -trendchip-dcp 3608/tcp # Trendchip control protocol -# Ming-Jen Chen September 2002 -cpdi-pidas-cm 3609/udp # CPDI PIDAS Connection Mon -cpdi-pidas-cm 3609/tcp # CPDI PIDAS Connection Mon -# Tony Splaver September 2002 -echonet 3610/udp # ECHONET -echonet 3610/tcp # ECHONET -# Takeshi Saito September 2002 -six-degrees 3611/udp # Six Degrees Port -six-degrees 3611/tcp # Six Degrees Port -# Dan Hansen September 2002 -hp-dataprotect 3612/udp # HP Data Protector -hp-dataprotect 3612/tcp # HP Data Protector -# Stephen Gold September 2002 -alaris-disc 3613/udp # Alaris Device Discovery -alaris-disc 3613/tcp # Alaris Device Discovery -# Chris McAllen October 2002 -sigma-port 3614/udp # Invensys Sigma Port -sigma-port 3614/tcp # Invensys Sigma Port -# Dr. Sajed Husein October 2002 -start-network 3615/udp # Start Messaging Network -start-network 3615/tcp # Start Messaging Network -# Peter Rocca October 2002 -cd3o-protocol 3616/udp # cd3o Control Protocol -cd3o-protocol 3616/tcp # cd3o Control Protocol -# Chris Wilcox October 2002 -sharp-server 3617/udp # ATI SHARP Logic Engine -sharp-server 3617/tcp # ATI SHARP Logic Engine -# Bill Reveile -aairnet-1 3618/udp # AAIR-Network 1 -aairnet-1 3618/tcp # AAIR-Network 1 -aairnet-2 3619/udp # AAIR-Network 2 -aairnet-2 3619/tcp # AAIR-Network 2 -# James Mealey October 2002 -ep-pcp 3620/udp # EPSON Projector Control Port -ep-pcp 3620/tcp # EPSON Projector Control Port -ep-nsp 3621/udp # EPSON Network Screen Port -ep-nsp 3621/tcp # EPSON Network Screen Port -# SEIKO EPSON October 2002 -ff-lr-port 3622/udp # FF LAN Redundancy Port -ff-lr-port 3622/tcp # FF LAN Redundancy Port -# Fieldbus Foundation October 2002 -haipe-discover 3623/udp # HAIPIS Dynamic Discovery -haipe-discover 3623/tcp # HAIPIS Dynamic Discovery -# Mike Irani October 2002 -dist-upgrade 3624/udp # Distributed Upgrade Port -dist-upgrade 3624/tcp # Distributed Upgrade Port -# Jason Schoon October 2002 -volley 3625/udp # Volley -volley 3625/tcp # Volley -# David Catmull October 2002 -bvcdaemon-port 3626/udp # bvControl Daemon -bvcdaemon-port 3626/tcp # bvControl Daemon -# Ravi Gokhale October 2002 -jamserverport 3627/udp # Jam Server Port -jamserverport 3627/tcp # Jam Server Port -# Art Pope October 2002 -ept-machine 3628/udp # EPT Machine Interface -ept-machine 3628/tcp # EPT Machine Interface -# Victor H. Farrace October 2002 -escvpnet 3629/udp # ESC/VP.net -escvpnet 3629/tcp # ESC/VP.net -# Hiroyuki Hashimoto October 2002 -cs-remote-db 3630/udp # C&S Remote Database Port -cs-remote-db 3630/tcp # C&S Remote Database Port -cs-services 3631/udp # C&S Web Services Port -cs-services 3631/tcp # C&S Web Services Port -# Computer Software GmbH October 2002 -distcc 3632/udp # distributed complier -distcc 3632/tcp # distributed compiler -# Martin Pool November 2002 -wacp 3633/udp # Wyrnix AIS port -wacp 3633/tcp # Wyrnix AIS port -# Harry T. Vennik November 2002 -hlibmgr 3634/udp # hNTSP Library Manager -hlibmgr 3634/tcp # hNTSP Library Manager -# Kenji Tetsuyama November 2002 -sdo 3635/udp # Simple Distributed Objects -sdo 3635/tcp # Simple Distributed Objects -# Alexander Philippou November 2002 -opscenter 3636/udp # OpsCenter -opscenter 3636/tcp # OpsCenter -# Ralph Campbell November 2002 -scservp 3637/udp # Customer Service Port -scservp 3637/tcp # Customer Service Port -# Jonathan A. Zdziarski November 2002 -ehp-backup 3638/udp # EHP Backup Protocol -ehp-backup 3638/tcp # EHP Backup Protocol -# Ed Fair November 2002 -xap-ha 3639/udp # Extensible Automation -xap-ha 3639/tcp # Extensible Automation -# Mark Harrison November 2002 -netplay-port1 3640/udp # Netplay Port 1 -netplay-port1 3640/tcp # Netplay Port 1 -netplay-port2 3641/udp # Netplay Port 2 -netplay-port2 3641/tcp # Netplay Port 2 -# Predrag Filipovic November 2002 -juxml-port 3642/udp # Juxml Replication port -juxml-port 3642/tcp # Juxml Replication port -# Colin Reid November 2002 -audiojuggler 3643/udp # AudioJuggler -audiojuggler 3643/tcp # AudioJuggler -# Morten Mertner November 2002 -ssowatch 3644/udp # ssowatch -ssowatch 3644/tcp # ssowatch -# Stephane Vinsot November 2002 -cyc 3645/udp # Cyc -cyc 3645/tcp # Cyc -# Stephen Reed January 2003 -xss-srv-port 3646/udp # XSS Server Port -xss-srv-port 3646/tcp # XSS Server Port -# Joe Purcell January 2003 -splitlock-gw 3647/udp # Splitlock Gateway -splitlock-gw 3647/tcp # Splitlock Gateway -# Andrew Tune January 2003 -fjcp 3648/udp # Fujitsu Cooperation Port -fjcp 3648/tcp # Fujitsu Cooperation Port -# Kouji Sugisawa January 2003 -nmmp 3649/udp # Nishioka Miyuki Msg Protocol -nmmp 3649/tcp # Nishioka Miyuki Msg Protocol -# TAKEDA Hiroyuki January 2003 -prismiq-plugin 3650/udp # PRISMIQ VOD plug-in -prismiq-plugin 3650/tcp # PRISMIQ VOD plug-in -# Richard Hodges January 2003 -xrpc-registry 3651/udp # XRPC Registry -xrpc-registry 3651/tcp # XRPC Registry -# Slava Monich January 2003 -vxcrnbuport 3652/udp # VxCR NBU Default Port -vxcrnbuport 3652/tcp # VxCR NBU Default Port -# Boris Star January 2003 -tsp 3653/udp # Tunnel Setup Protocol -tsp 3653/tcp # Tunnel Setup Protocol -# Marc Blanchet January 2003 -vaprtm 3654/udp # VAP RealTime Messenger -vaprtm 3654/tcp # VAP RealTime Messenger -# Boris Polevoy January 2003 -abatemgr 3655/udp # ActiveBatch Exec Agent -abatemgr 3655/tcp # ActiveBatch Exec Agent -abatjss 3656/udp # ActiveBatch Job Scheduler -abatjss 3656/tcp # ActiveBatch Job Scheduler -# Ben Rosenberg January 2003 -immedianet-bcn 3657/udp # ImmediaNet Beacon -immedianet-bcn 3657/tcp # ImmediaNet Beacon -# Bill Homan January 2003 -ps-ams 3658/udp # PlayStation AMS (Secure) -ps-ams 3658/tcp # PlayStation AMS (Secure) -# Edgar Alan Tu January 2003 -apple-sasl 3659/udp # Apple SASL -apple-sasl 3659/tcp # Apple SASL -# David M. O'Rourke January 2003 -can-nds-ssl 3660/udp # Candle Directory Services using SSL -can-nds-ssl 3660/tcp # Candle Directory Services using SSL -can-ferret-ssl 3661/udp # Candle Directory Services using SSL -can-ferret-ssl 3661/tcp # Candle Directory Services using SSL -# Nic Catrambone January 2003 -pserver 3662/udp # pserver -pserver 3662/tcp # pserver -# Patrick Furlong January 2003 -dtp 3663/udp # DIRECWAY Tunnel Protocol -dtp 3663/tcp # DIRECWAY Tunnel Protocol -# Greg Gee January 2003 -ups-engine 3664/udp # UPS Engine Port -ups-engine 3664/tcp # UPS Engine Port -ent-engine 3665/udp # Enterprise Engine Port -ent-engine 3665/tcp # Enterprise Engine Port -# Mike Delgrosso January 2003 -eserver-pap 3666/udp # IBM EServer PAP -eserver-pap 3666/tcp # IBM eServer PAP -# Dave Gimpl January 2003 -infoexch 3667/udp # IBM Information Exchange -infoexch 3667/tcp # IBM Information Exchange -# Paul Ford-Hutchinson January 2003 -dell-rm-port 3668/udp # Dell Remote Management -dell-rm-port 3668/tcp # Dell Remote Management -# Bradley Bransom January 2003 -casanswmgmt 3669/udp # CA SAN Switch Management -casanswmgmt 3669/tcp # CA SAN Switch Management -# Emre Tunar January 2003 -smile 3670/udp # SMILE TCP/UDP Interface -smile 3670/tcp # SMILE TCP/UDP Interface -# Andre Petras January 2003 -efcp 3671/udp # e Field Control (EIBnet) -efcp 3671/tcp # e Field Control (EIBnet) -# Marc Goossens January 2003 -lispworks-orb 3672/udp # LispWorks ORB -lispworks-orb 3672/tcp # LispWorks ORB -# Lisp Support -mediavault-gui 3673/udp # Openview Media Vault GUI -mediavault-gui 3673/tcp # Openview Media Vault GUI -# Stephen Gold January 2003 -wininstall-ipc 3674/udp # WinINSTALL IPC Port -wininstall-ipc 3674/tcp # WinINSTALL IPC Port -# Bill Somerville January 2003 -calltrax 3675/udp # CallTrax Data Port -calltrax 3675/tcp # CallTrax Data Port -# Oliver Bailey January 2003 -va-pacbase 3676/udp # VisualAge Pacbase server -va-pacbase 3676/tcp # VisualAge Pacbase server -# Dominique Lelievre January 2003 -roverlog 3677/udp # RoverLog IPC -roverlog 3677/tcp # RoverLog IPC -# Tom Mayo January 2003 -ipr-dglt 3678/udp # DataGuardianLT -ipr-dglt 3678/tcp # DataGuardianLT -# Bruce Carlson January 2003 -newton-dock 3679/udp # Newton Dock -newton-dock 3679/tcp # Newton Dock -npds-tracker 3680/udp # NPDS Tracker -npds-tracker 3680/tcp # NPDS Tracker -# Paul Guyot January 2003 -bts-x73 3681/udp # BTS X73 Port -bts-x73 3681/tcp # BTS X73 Port -# Todd Cooper January 2003 -cas-mapi 3682/udp # EMC SmartPackets-MAPI -cas-mapi 3682/tcp # EMC SmartPackets-MAPI -# Koen Schoofs January 2003 -bmc-ea 3683/udp # BMC EDV/EA -bmc-ea 3683/tcp # BMC EDV/EA -# Jeffrey Glanz January 2003 -faxstfx-port 3684/udp # FAXstfX -faxstfx-port 3684/tcp # FAXstfX -# Alec Carlson January 2003 -dsx-agent 3685/udp # DS Expert Agent -dsx-agent 3685/tcp # DS Expert Agent -# NetPro Computing January 2003 -tnmpv2 3686/udp # Trivial Network Management -tnmpv2 3686/tcp # Trivial Network Management -# Andrea Premoli January 2003 -simple-push 3687/udp # simple-push -simple-push 3687/tcp # simple-push -simple-push-s 3688/udp # simple-push Secure -simple-push-s 3688/tcp # simple-push Secure -# C. Enrique Ortiz January 2003 -daap 3689/udp # Digital Audio Access Protocol -daap 3689/tcp # Digital Audio Access Protocol -# Amandeep Jawa January 2003 -svn 3690/udp # Subversion -svn 3690/tcp # Subversion -# Greg Hudson January 2003 -magaya-network 3691/udp # Magaya Network Port -magaya-network 3691/tcp # Magaya Network Port -# Jesus David Rodriguez February 2003 -intelsync 3692/udp # Brimstone IntelSync -intelsync 3692/tcp # Brimstone IntelSync -# Davey Taylor February 2003 -gttp 3693/udp # GTTP -gttp 3693/tcp # GTTP -vpncpp 3694/udp # VPN Cookie Prop Protocol -vpncpp 3694/tcp # VPN Cookie Prop Protocol -# Rondald P. Bonica February 2003 -bmc-data-coll 3695/udp # BMC Data Collection -bmc-data-coll 3695/tcp # BMC Data Collection -# Randall De Weerd February 2003 -telnetcpcd 3696/udp # Telnet Com Port Control -telnetcpcd 3696/tcp # Telnet Com Port Control -# Thomas J. Pinkl February 2003 -nw-license 3697/udp # NavisWorks Licnese System -nw-license 3697/tcp # NavisWorks License System -# Tim Wiegand February 2003 -sagectlpanel 3698/udp # SAGECTLPANEL -sagectlpanel 3698/tcp # SAGECTLPANEL -# Mark Gamble February 2003 -kpn-icw 3699/udp # Internet Call Waiting -kpn-icw 3699/tcp # Internet Call Waiting -# B.J. Kortekaas February 2003 -lrs-paging 3700/udp # LRS NetPage -lrs-paging 3700/tcp # LRS NetPage -# Geoffrey Wossum February 2003 -netcelera 3701/udp # NetCelera -netcelera 3701/tcp # NetCelera -# Tarek Nabhan February 2003 -upnp-discovery 3702/udp # UPNP v2 Discovery -upnp-discovery 3702/tcp # UPNP v2 Discovery -# Christian Huitema February 2003 -adobeserver-3 3703/udp # Adobe Server 3 -adobeserver-3 3703/tcp # Adobe Server 3 -adobeserver-4 3704/udp # Adobe Server 4 -adobeserver-4 3704/tcp # Adobe Server 4 -adobeserver-5 3705/udp # Adobe Server 5 -adobeserver-5 3705/tcp # Adobe Server 5 -# Frank Soetebeer January 2003 -rt-event 3706/udp # Real-Time Event Port -rt-event 3706/tcp # Real-Time Event Port -rt-event-s 3707/udp # Real-Time Event Secure Port -rt-event-s 3707/tcp # Real-Time Event Secure Port -# Terry Gin February 2003 -# 3708 Unassigned -ca-idms 3709/udp # CA-IDMS Server -ca-idms 3709/tcp # CA-IDMS Server -# Dave Ross -portgate-auth 3710/udp # PortGate Authentication -portgate-auth 3710/tcp # PortGate Authentication -# Scott Harris February 2003 -edb-server2 3711/udp # EBD Server 2 -edb-server2 3711/tcp # EBD Server 2 -# Carlos Portela February 2003 -sentinel-ent 3712/udp # Sentinel Enterprise -sentinel-ent 3712/tcp # Sentinel Enterprise -# Ian Gordon March 2003 -tftps 3713/udp # TFTP over TLS -tftps 3713/tcp # TFTP over TLS -# Mark mayernick March 2003 -delos-dms 3714/udp # DELOS Direct Messaging -delos-dms 3714/tcp # DELOS Direct Messaging -# Ekkehard Morgenstern March 2003 -anoto-rendezv 3715/udp # Anoto Rendezvous Port -anoto-rendezv 3715/tcp # Anoto Rendezvous Port -# Ola Sandstrom March 2003 -wv-csp-sms-cir 3716/udp # WV CSP SMS CIR Channel -wv-csp-sms-cir 3716/tcp # WV CSP SMS CIR Channel -wv-csp-udp-cir 3717/udp # WV CSP UDP/IP CIR Channel -wv-csp-udp-cir 3717/tcp # WV CSP UDP/IP CIR Channel -# Jon Ingi Ingimundarson March 2003 -opus-services 3718/udp # OPUS Server Port -opus-services 3718/tcp # OPUS Server Port -# Detlef Stoever March 2003 -itelserverport 3719/udp # iTel Server Port -itelserverport 3719/tcp # iTel Server Port -# Mark Hendricks March 2003 -ufastro-instr 3720/udp # UF Astro. Instr. Services -ufastro-instr 3720/tcp # UF Astro. Instr. Services -# David B. Hon March 2003 -xsync 3721/udp # Xsync -xsync 3721/tcp # Xsync -xserveraid 3722/udp # Xserver RAID -xserveraid 3722/tcp # Xserver RAID -# Bob Bradley March 2003 -sychrond 3723/udp # Sychron Service Daemon -sychrond 3723/tcp # Sychron Service Daemon -# Robert Marinelli March 2003 -battlenet 3724/udp # Blizzard Battlenet -battlenet 3724/tcp # Blizzard Battlenet -# Adrian Luff March 2003 -na-er-tip 3725/udp # Netia NA-ER Port -na-er-tip 3725/tcp # Netia NA-ER Port -# Jean-Pierre Garcia April 2003 -array-manager 3726/udp # Xyartex Array Manager -array-manager 3726/tcp # Xyratex Array Manager -# David A. Lethe April 2003 -e-mdu 3727/udp # Ericsson Mobile Data Unit -e-mdu 3727/tcp # Ericsson Mobile Data Unit -e-woa 3728/udp # Ericsson Web on Air -e-woa 3728/tcp # Ericsson Web on Air -# Marco Casole April 2003 -fksp-audit 3729/udp # Fireking Audit Port -fksp-audit 3729/tcp # Fireking Audit Port -# Richard Thurman April 2003 -client-ctrl 3730/udp # Client Control -client-ctrl 3730/tcp # Client Control -# Lawrence W. Dunn April 2003 -smap 3731/udp # Service Manager -smap 3731/tcp # Service Manager -m-wnn 3732/udp # Mobile Wnn -m-wnn 3732/tcp # Mobile Wnn -# Yasunari Yamashita April 2003 -multip-msg 3733/udp # Multipuesto Msg Port -multip-msg 3733/tcp # Multipuesto Msg Port -# Felisa Ares April 2003 -synel-data 3734/udp # Synel Data Collection Port -synel-data 3734/tcp # Synel Data Collection Port -# David Ashkenazi April 2003 -pwdis 3735/udp # Password Distribution -pwdis 3735/tcp # Password Distribution -# Robert Erl April 2003 -rs-rmi 3736/udp # RealSpace RMI -rs-rmi 3736/tcp # RealSpace RMI -# Barry McDarby April 2003 -# 3737 Unassigned (Removed 2003-02-26) -versatalk 3738/udp # versaTalk Server Port -versatalk 3738/tcp # versaTalk Server Port -# Dr. Kingsley C. Nwosu April 2003 -launchbird-lm 3739/udp # Launchbird LicenseManager -launchbird-lm 3739/tcp # Launchbird LicenseManager -# Tom Hawkins April 2003 -heartbeat 3740/udp # Heartbeat Protocol -heartbeat 3740/tcp # Heartbeat Protocol -# Jeroen Massar April 2003 -wysdma 3741/udp # WysDM Agent -wysdma 3741/tcp # WysDM Agent -# Jim McDonald April 2003 -cst-port 3742/udp # CST - Configuration & Service Tracker -cst-port 3742/tcp # CST - Configuration & Service Tracker -# Hai Ou-Yang April 2003 -ipcs-command 3743/udp # IP Control Systems Ltd. -ipcs-command 3743/tcp # IP Control Systems Ltd. -# Paul Anderson April 2003 -sasg 3744/udp # SASG -sasg 3744/tcp # SASG -# Cristian Petculescu April 2003 -gw-call-port 3745/udp # GWRTC Call Port -gw-call-port 3745/tcp # GWRTC Call Port -# Felisa Ares April 2003 -linktest 3746/udp # LXPRO.COM LinkTest -linktest 3746/tcp # LXPRO.COM LinkTest -linktest-s 3747/udp # LXPRO.COM LinkTest SSL -linktest-s 3747/tcp # LXPRO.COM LinkTest SSL -# Greg Bailey April 2003 -webdata 3748/udp # webData -webdata 3748/tcp # webData -# Michael Whiteley April 2003 -cimtrak 3749/udp # CimTrak -cimtrak 3749/tcp # CimTrak -cbos-ip-port 3750/udp # CBOS/IP ncapsalatoin port -cbos-ip-port 3750/tcp # CBOS/IP ncapsalation port -# Thomas Dannemiller April 2003 -gprs-cube 3751/udp # CommLinx GPRS Cube -gprs-cube 3751/tcp # CommLinx GPRS Cube -# Peter Johnson April 2003 -vipremoteagent 3752/udp # Vigil-IP RemoteAgent -vipremoteagent 3752/tcp # Vigil-IP RemoteAgent -# Bryan Alvord April 2003 -nattyserver 3753/udp # NattyServer Port -nattyserver 3753/tcp # NattyServer Port -# Akira Saito April 2003 -timestenbroker 3754/udp # TimesTen Broker Port -timestenbroker 3754/tcp # TimesTen Broker Port -# David Aspinwall April 2003 -sas-remote-hlp 3755/udp # SAS Remote Help Server -sas-remote-hlp 3755/tcp # SAS Remote Help Server -# Gary T. Ciampa April 2003 -canon-capt 3756/udp # Canon CAPT Port -canon-capt 3756/tcp # Canon CAPT Port -# Takashi Okazawa April 2003 -grf-port 3757/udp # GRF Server Port -grf-port 3757/tcp # GRF Server Port -# Robert Banfill April 2003 -apw-registry 3758/udp # apw RMI registry -apw-registry 3758/tcp # apw RMI registry -# Dan Davis April 2003 -exapt-lmgr 3759/udp # Exapt License Manager -exapt-lmgr 3759/tcp # Exapt License Manager -# Christoph Kukulies April 2003 -adtempusclient 3760/udp # adTEmpus Client -adtempusclient 3760/tcp # adTempus Client -# Bill Wingate May 2003 -gsakmp 3761/udp # gsakmp port -gsakmp 3761/tcp # gsakmp port -# Uri Meth June 2003 -gbs-smp 3762/udp # GBS SnapMail Protocol -gbs-smp 3762/tcp # GBS SnapMail Protocol -# Eric Harris-Braun June 2003 -xo-wave 3763/udp # XO Wave Control Port -xo-wave 3763/tcp # XO Wave Control Port -# Bjorn Dittmer-Roche June 2003 -mni-prot-rout 3764/udp # MNI Protected Routing -mni-prot-rout 3764/tcp # MNI Protected Routing -# Tim Behne June 2003 -rtraceroute 3765/udp # Remote Traceroute -rtraceroute 3765/tcp # Remote Traceroute -# A. Blake Cooper June 2003 -listmgr-port 3767/udp # ListMGR Port -listmgr-port 3767/tcp # ListMGR Port -# Takashi Kubota June 2003 -rblcheckd 3768/udp # rblcheckd server daemon -rblcheckd 3768/tcp # rblcheckd server daemon -# Sabri Berisha June 2003 -haipe-otnk 3769/udp # HAIPE Network Keying -haipe-otnk 3769/tcp # HAIPE Network Keying -# Mike Irani June 2003 -cindycollab 3770/udp # Cinderella Collaboration -cindycollab 3770/tcp # Cinderella Collaboration -# Ulrich Kortenkamp June 2003 -paging-port 3771/udp # RTP Paging Port -paging-port 3771/tdp # RTP Paging Port -# Patrick Ferriter June 2003 -ctp 3772/udp # Chantry Tunnel Protocol -ctp 3772/tcp # Chantry Tunnel Protocol -# Inderpreet Singh June 2003 -ctdhercules 3773/udp # ctdhercules -ctdhercules 3773/tcp # ctdhercules -# Carl Banzhof June 2003 -zicom 3774/udp # ZICOM -zicom 3774/tcp # ZICOM -# Sabu Das June 2003 -ispmmgr 3775/udp # ISPM Manager Port -ispmmgr 3775/tcp # ISPM Manager Port -# Eric Anderson June 2003 -# 3776 Unassigned -jibe-eb 3777/udp # Jibe EdgeBurst -jibe-eb 3777/tcp # Jibe EdgeBurst -# Chap Tippin June 2003 -c-h-it-port 3778/udp # Cutler-Hammer IT Port -c-h-it-port 3778/tcp # Cutler-Hammer IT Port -# Thomas Ruchti June 2003 -cognima 3779/udp # Cognima Replication -cognima 3779/tcp # Cognima Replication -# Raplh Grenwell June 2003 -nnp 3780/udp # Nuzzler Network Protocol -nnp 3780/tcp # Nuzzler Network Protocol -# Andreas Schwarz June 2003 -abcvoice-port 3781/udp # ABCvoice server port -abcvoice-port 3781/tcp # ABCvoice server port -# Carlos Gonzalez-Roman Ferrer June 2003 -iso-tp0s 3782/udp # Secure ISO TP0 port -iso-tp0s 3782/tcp # Secure ISO TP0 port -# Herbert Falk June 2003 -# 3783-3799 Unassigned -pwgpsi 3800/udp # Print Services Interface -pwgpsi 3800/tcp # Print Services Interface -# Harry Lewis May 2003 -# 3801 Unassigned -vhd 3802/udp # VHD -vhd 3802/tcp # VHD -# Chris Duncombe -# 3803-3844 Unassigned -v-one-spp 3845/udp # V-ONE Single Port Proxy -v-one-spp 3845/tcp # V-ONE Single Port Proxy -# Daniel Becker -# 3846-3860 Unassigned -winshadow-hd 3861/udp # winShadow Host Discovery -winshadow-hd 3861/tcp # winShadow Host Discovery -# Shu-Wei Tan March 2003 -giga-pocket 3862/udp # GIGA-POCKET -giga-pocket 3862/tcp # GIGA-POCKET -# Yoshikazu Watanabe -# 3863-3874 Unassigned -pnbscada 3875/udp # PNBSCADA -pnbscada 3875/tcp # PNBSCADA -# Philip N. Bergstresser -# 3876-3884 Unassigned -topflow-ssl 3885/udp # TopFlow SSL -topflow-ssl 3885/tcp # TopFlow SSL -# Ken Nelson -# 3886-3899 Unassigned -udt_os 3900/udp # Unidata UDT OS -udt_os 3900/tcp # Unidata UDT OS -# James Powell -# 3901-3938 Unassigned -aamp 3939/udp # Anti-virus Application Management Port -aamp 3939/tcp # Anti-virus Application Management Port -# In-sik Choi February 2002 -# 3940-3983 Unassigned -mapper-nodemgr 3984/udp # MAPPER network node manager -mapper-nodemgr 3984/tcp # MAPPER network node manager -mapper-mapethd 3985/udp # MAPPER TCP/IP server -mapper-mapethd 3985/tcp # MAPPER TCP/IP server -mapper-ws_ethd 3986/udp # MAPPER workstation server -mapper-ws_ethd 3986/tcp # MAPPER workstation server -# John C. Horton -centerline 3987/udp # Centerline -centerline 3987/tcp # Centerline -# Mark Simpson -# 3988-3999 Unassigned -terabase 4000/udp # Terabase -terabase 4000/tcp # Terabase -# Thor Olson -####### Potential Conflict of ports ################################ -####### PORT 4000 also used by ICQ ################### -newoak 4001/udp # NewOak -newoak 4001/tcp # NewOak -# Jim Philippou -pxc-spvr-ft 4002/udp # pxc-spvr-ft -pxc-spvr-ft 4002/tcp # pxc-spvr-ft -pxc-splr-ft 4003/udp # pxc-splr-ft -pxc-splr-ft 4003/tcp # pxc-splr-ft -pxc-roid 4004/udp # pxc-roid -pxc-roid 4004/tcp # pxc-roid -pxc-pin 4005/udp # pxc-pin -pxc-pin 4005/tcp # pxc-pin -pxc-spvr 4006/udp # pxc-spvr -pxc-spvr 4006/tcp # pxc-spvr -pxc-splr 4007/udp # pxc-splr -pxc-splr 4007/tcp # pxc-splr -# Dave Nesbitt -netcheque 4008/udp # NetCheque accounting -netcheque 4008/tcp # NetCheque accounting -# B. Clifford Neuman -chimera-hwm 4009/udp # Chimera HWM -chimera-hwm 4009/tcp # Chimera HWM -# Ken Anderson -samsung-unidex 4010/udp # Samsung Unidex -samsung-unidex 4010/tcp # Samsung Unidex -# Konstantin V. Vyaznikov -altserviceboot 4011/udp # Alternate Service Boot -altserviceboot 4011/tcp # Alternate Service Boot -# Eric Dittert -pda-gate 4012/udp # PDA Gate -pda-gate 4012/tcp # PDA Gate -# Masakuni Okada -acl-manager 4013/udp # ACL Manager -acl-manager 4013/tcp # ACL Manager -# Toru Murai -taiclock 4014/udp # TAICLOCK -taiclock 4014/tcp # TAICLOCK -# Dan Bernstein -talarian-mcast1 4015/udp # Talarian Mcast -talarian-mcast1 4015/tcp # Talarian Mcast -talarian-mcast2 4016/udp # Talarian Mcast -talarian-mcast2 4016/tcp # Talarian Mcast -talarian-mcast3 4017/udp # Talarian Mcast -talarian-mcast3 4017/tcp # Talarian Mcast -talarian-mcast4 4018/udp # Talarian Mcast -talarian-mcast4 4018/tcp # Talarian Mcast -talarian-mcast5 4019/udp # Talarian Mcast -talarian-mcast5 4019/tcp # Talarian Mcast -# Geoff Mendal -trap 4020/udp # TRAP Port -trap 4020/tcp # TRAP Port -# Jeffrey C. Byrd -nexus-portal 4021/udp # Nexus Portal -nexus-portal 4021/tcp # Nexus Portal -# Damian Tarnawsky -dnox 4022/udp # DNOX -dnox 4022/tcp # DNOX -# Leo Rathnayake -esnm-zoning 4023/udp # ESNM Zoning Port -esnm-zoning 4023/tcp # ESNM Zoning Port -# Yong Cai -tnp1-port 4024/udp # TNP1 User Port -tnp1-port 4024/tcp # TNP1 User Port -# Tony Gibbs -partimage 4025/udp # Partition Image Port -partimage 4025/tcp # Partition Image Port -# Franck Ladurelle -as-debug 4026/udp # Graphical Debug Server -as-debug 4026/tcp # Graphical Debug Server -# Steve Halverson -bxp 4027/udp # bitxpress -bxp 4027/tcp # bitxpress -# Morgan Doyle -dtserver-port 4028/udp # DTServer Port -dtserver-port 4028/tcp # DTServer Port -# Stephen Aikins -ip-qsig 4029/udp # IP Q signaling protocol -ip-qsig 4029/tcp # IP Q signaling protocol -# Toru Tachibana -jdmn-port 4030/udp # Accell/JSP Daemon Port -jdmn-port 4030/tcp # Accell/JSP Daemon Port -# Art Grand -suucp 4031/udp # UUCP over SSL -suucp 4031/tcp # UUCP over SSL -# Harald Welte -vrts-auth-port 4032/udp # VERITAS Authorization Service -vrts-auth-port 4032/tcp # VERITAS Authorization Service -# Stefan Winkel -sanavigator 4033/udp # SANavigator Peer Port -sanavigator 4033/tcp # SANavigator Peer Port -# Robert J. Chansler -ubxd 4034/udp # Ubiquinox Daemon -ubxd 4034/tcp # Ubiquinox Daemon -# Kit Smithers -wap-push-http 4035/udp # WAP Push OTA-HTTP port -wap-push-http 4035/tcp # WAP Push OTA-HTTP port -wap-push-https 4036/udp # WAP Push OTA-HTTP secure -wap-push-https 4036/tcp # WAP Push OTA-HTTP secure -# Matthieu Lachance -# -# 4037-4039 Unassigned -yo-main 4040/udp # Yo.net main service -yo-main 4040/tcp # Yo.net main service -# John Tintor -houston 4041/udp # Rocketeer-Houston -houston 4041/tcp # Rocketeer-Houston -# Johnny C. Norris II -ldxp 4042/udp # LDXP -ldxp 4042/tcp # LDXP -# Craig Calef -# 4043-4095 Unassigned -bre 4096/udp # BRE (Bridge Relay Element) -bre 4096/tcp # BRE (Bridge Relay Element) -# Stephen Egbert -patrolview 4097/udp # Patrol View -patrolview 4097/tcp # Patrol View -# Vincent Chin -drmsfsd 4098/udp # drmsfsd -drmsfsd 4098/tcp # drmsfsd -# Masao Iwai -dpcp 4099/udp # DPCP -dpcp 4099/tcp # DPCP -# John Croft -igo-incognito 4100/udp # IGo Incognito Data Port -igo-incognito 4100/tcp # IGo Incognito Data Port -# Paul Reddy February 2002 -# 4101-4110 Unassigned -xgrid 4111/tcp # Xgrid -xgrid 4111/udp # Xgrid -jomamqmonitor 4114/udp # JomaMQMonitor -jomamqmonitor 4114/tcp # JomaMQMonitor -# Marcel Hofstetter January 2003 -# 4115-4131 Unassigned -nuts_dem 4132/udp # NUTS Daemon -nuts_dem 4132/tcp # NUTS Daemon -nuts_bootp 4133/udp # NUTS Bootp Server -nuts_bootp 4133/tcp # NUTS Bootp Server -# Martin Freiss -nifty-hmi 4134/udp # NIFTY-Serve HMI protocol -nifty-hmi 4134/tcp # NIFTY-Serve HMI protocol -# Ryuichi Suzuki -# 4135-4137 Unassigned -nettest 4138/udp # nettest -nettest 4138/tcp # nettest -# David Borman March 2003 -# 4139-4140 Unassigned -oirtgsvc 4141/udp # Workflow Server -oirtgsvc 4141/tcp # Workflow Server -oidocsvc 4142/udp # Document Server -oidocsvc 4142/tcp # Document Server -oidsr 4143/udp # Document Replication -oidsr 4143/tcp # Document Replication -# Norman Brie -########## Compuserve (unoffically) is using port 4144 ######### -# 4144 Unassigned -vvr-control 4145/udp # VVR Control -vvr-control 4145/tcp # VVR Control -# Ming Xu -# 4146-4153 Unassigned -atlinks 4154/udp # atlinks device discovery -atlinks 4154/tcp # atlinks device discovery -# Scott Griepentrog October 2002 -# 4155-4159 Unassigned -jini-discovery 4160/udp # Jini Discovery -jini-discovery 4160/tcp # Jini Discovery -# Mark Hodapp -# 4161-4198 Unassigned -eims-admin 4199/udp # EIMS ADMIN -eims-admin 4199/tcp # EIMS ADMIN -# Glenn Anderson -# Mitra -corelccam 4300/udp # Corel CCam -corelccam 4300/tcp # Corel CCam -# Jason Aiken -# 4301-4320 Unassigned -rwhois 4321/udp # Remote Who Is -rwhois 4321/tcp # Remote Who Is -# Mark Kosters -unicall 4343/udp # UNICALL -unicall 4343/tcp # UNICALL -# James Powell -vinainstall 4344/udp # VinaInstall -vinainstall 4344/tcp # VinaInstall -# Jay Slupesky -m4-network-as 4345/udp # Macro 4 Network AS -m4-network-as 4345/tcp # Macro 4 Network AS -# Paul Wren -elanlm 4346/udp # ELAN LM -elanlm 4346/tcp # ELAN LM -# Paul Ballew -lansurveyor 4347/udp # LAN Surveyor -lansurveyor 4347/tcp # LAN Surveyor -# Michael Swan -itose 4348/udp # ITOSE -itose 4348/tcp # ITOSE -# Michael Haeuptle -fsportmap 4349/udp # File System Port Map -fsportmap 4349/tcp # File System Port Map -# Ron Minnich -net-device 4350/udp # Net Device -net-device 4350/tcp # Net Device -# Glenn Peterson -plcy-net-svcs 4351/udp # PLCY Net Services -plcy-net-svcs 4351/tcp # PLCY Net Services -# J.J. Ekstrom -# 4352 Unassigned -f5-iquery 4353/udp # F5 iQuery -f5-iquery 4353/tcp # F5 iQuery -# Tom Kee -qsnet-trans 4354/udp # QSNet Transmitter -qsnet-trans 4354/tcp # QSNet Transmitter -qsnet-workst 4355/udp # QSNet Workstation -qsnet-workst 4355/tcp # QSNet Workstation -qsnet-assist 4356/udp # QSNet Assistant -qsnet-assist 4356/tcp # QSNet Assistant -qsnet-cond 4357/udp # QSNet Conductor -qsnet-cond 4357/tcp # QSNet Conductor -qsnet-nucl 4358/udp # QSNet Nucleus -qsnet-nucl 4358/tcp # QSNet Nucleus -# Neer Kleinman -# 4359-4441 Unassigned -saris 4442/udp # Saris -saris 4442/tcp # Saris -pharos 4443/udp # Pharos -pharos 4443/tcp # Pharos -# TeleConsult GmbH, 76275 Ettlingen, Germany -# -krb524 4444/udp # KRB524 -krb524 4444/tcp # KRB524 -# B. Clifford Neuman -# PROBLEM krb524 assigned the port, -# PROBLEM nv used it without an assignment -nv-video 4444/udp # NV Video default -nv-video 4444/tcp # NV Video default -# Ron Frederick -upnotifyp 4445/udp # UPNOTIFYP -upnotifyp 4445/tcp # UPNOTIFYP -# Mark Fox -n1-fwp 4446/udp # N1-FWP -n1-fwp 4446/tcp # N1-FWP -n1-rmgmt 4447/udp # N1-RMGMT -n1-rmgmt 4447/tcp # N1-RMGMT -# Lori Tassin -asc-slmd 4448/udp # ASC Licence Manager -asc-slmd 4448/tcp # ASC Licence Manager -# Casper Stoel -privatewire 4449/udp # PrivateWire -privatewire 4449/tcp # PrivateWire -# Uri Resnitzky -camp 4450/udp # Camp -camp 4450/tcp # Camp -ctisystemmsg 4451/udp # CTI System Msg -ctisystemmsg 4451/tcp # CTI System Msg -ctiprogramload 4452/udp # CTI Program Load -ctiprogramload 4452/tcp # CTI Program Load -# Steven Cliff -nssalertmgr 4453/udp # NSS Alert Manager -nssalertmgr 4453/tcp # NSS Alert Manager -nssagentmgr 4454/udp # NSS Agent Manager -nssagentmgr 4454/tcp # NSS Agent Manager -# Jim Hill -prchat-user 4455/udp # PR Chat User -prchat-user 4455/tcp # PR Chat User -prchat-server 4456/udp # PR Chat Server -prchat-server 4456/tcp # PR Chat Server -prRegister 4457/udp # PR Register -prRegister 4457/tcp # PR Register -# Donny Gilor -# 4458-4499 Unassigned -ipsec-msft 4500/udp # Microsoft IPsec NAT-T -ipsec-msft 4500/tcp # Microsoft IPsec NAT-T -# Christian Huitema March 2002 -# 4501 De-registered (08 June 2001) -# IANA -# 4502-4544 Unassigned -worldscores 4545/udp # WorldScores -worldscores 4545/tcp # WorldScores -# Steve Davis -sf-lm 4546/udp # SF License Manager (Sentinel) -sf-lm 4546/tcp # SF License Manager (Sentinel) -# Thomas Koell -lanner-lm 4547/udp # Lanner License Manager -lanner-lm 4547/tcp # Lanner License Manager -# Les Enstone -# 4548-4554 Unassigned -rsip 4555/udp # RSIP Port -rsip 4555/tcp # RSIP Port -# RFC 3103 -# 4556-4558 Unassigned -hylafax 4559/udp # HylaFAX -hylafax 4559/tcp # HylaFAX -# Lee Howard March 2002 -# 4560-4566 Unassigned -tram 4567/udp # TRAM -tram 4567/tcp # TRAM -# Joe Wesley -bmc-reporting 4568/udp # BMC Reporting -bmc-reporting 4568/tcp # BMC Reporting -# Randall De Weerd -# 4569-4599 Unassigned -piranha1 4600/udp # Piranha1 -piranha1 4600/tcp # Piranha1 -piranha2 4601/udp # Piranha2 -piranha2 4601/tcp # Piranha2 -# Primark Corporation -# 4602-4659 Unassigned -smaclmgr 4660/udp # smaclmgr -smaclmgr 4660/tcp # smaclmgr -# Hiromi Taki -kar2ouche 4661/udp # Kar2ouche Peer location service -kar2ouche 4661/tcp # Kar2ouche Peer location service -# Andy Krouwel -# 4662-4671 Unassigned -rfa 4672/udp # remote file access server -rfa 4672/tcp # remote file access server -# 4673-4751 Unassigned -snap 4752/udp # Simple Network Audio Protocol -snap 4752/tcp # Simple Network Audio Protocol -# Dameon Wagner February 2002 -# 4753-4799 Unassigned -iims 4800/udp # Icona Instant Messenging System -iims 4800/tcp # Icona Instant Messenging System -iwec 4801/udp # Icona Web Embedded Chat -iwec 4801/tcp # Icona Web Embedded Chat -ilss 4802/udp # Icona License System Server -ilss 4802/tcp # Icona License System Server -# Paul Stephen Borlie -# 4803-4826 Unassigned -htcp 4827/udp # HTCP -htcp 4827/tcp # HTCP -# Paul Vixie -# 4828-4836 Unassigned -varadero-0 4837/udp # Varadero-0 -varadero-0 4837/tcp # Varadero-0 -varadero-1 4838/udp # Varadero-1 -varadero-1 4838/tcp # Varadero-1 -varadero-2 4839/udp # Varadero-2 -varadero-2 4839/tcp # Varadero-2 -# Carlos Arteaga -# 4840-4847 Unassigned -appserv-http 4848/udp # App Server - Admin HTTP -appserv-http 4848/tcp # App Server - Admin HTTP -appserv-https 4849/udp # App Server - Admin HTTPS -appserv-https 4849/tcp # App Server - Admin HTTPS -# Sreeram Duvvuru April 2002 -# 4850-4867 Unassigned -phrelay 4868/udp # Photon Relay -phrelay 4868/tcp # Photon Relay -phrelaydbg 4869/udp # Photon Relay Debug -phrelaydbg 4869/tcp # Photon Relay Debug -# Michael Hunter -# 4870-4884 Unassigned -abbs 4885/udp # ABBS -abbs 4885/tcp # ABBS -# Ryan Rubley -# 4886-4893 Unassigned -lyskom 4894/udp # LysKOM Protocol A -lyskom 4894/tcp # LysKOM Protocol A -# Per Cederqvist -# 4895-4898 Unassigned -radmin-port 4899/udp # RAdmin Port -radmin-port 4899/tcp # RAdmin Port -# Dmitri Znosko March 2003 -# 4900-4982 Unassigned -att-intercom 4983/udp # AT&T Intercom -att-intercom 4983/tcp # AT&T Intercom -# Tony Hansen -# 4984-4986 Unassigned -smar-se-port1 4987/udp # SMAR Ethernet Port 1 -smar-se-port1 4987/tcp # SMAR Ethernet Port 1 -smar-se-port2 4988/udp # SMAR Ethernet Port 2 -smar-se-port2 4988/tcp # SMAR Ethernet Port 2 -# Delcio Prizon -parallel 4989/udp # Parallel for GAUSS (tm) -parallel 4989/tcp # Parallel for GAUSS (tm) -# Matthew Ford March 2003 -# 4990-4999 Unassigned -commplex-main 5000/udp # -commplex-main 5000/tcp # -commplex-link 5001/udp # -commplex-link 5001/tcp # -rfe 5002/udp # radio free ethernet -rfe 5002/tcp # radio free ethernet -fmpro-internal 5003/udp # FileMaker, Inc. - Proprietary name binding -fmpro-internal 5003/tcp # FileMaker, Inc. - Proprietary transport -# Clay Maeckel -avt-profile-1 5004/udp # avt-profile-1 -avt-profile-1 5004/tcp # avt-profile-1 -avt-profile-2 5005/udp # avt-profile-2 -avt-profile-2 5005/tcp # avt-profile-2 -# Henning Schulzrinne -wsm-server 5006/udp # wsm server -wsm-server 5006/tcp # wsm server -wsm-server-ssl 5007/udp # wsm server ssl -wsm-server-ssl 5007/tcp # wsm server ssl -# Adam Berk -synapsis-edge 5008/udp # Synapsis EDGE -synapsis-edge 5008/tcp # Synapsis EDGE -# Paul Schilling -# 5009 Unassigned -telelpathstart 5010/udp # TelepathStart -telelpathstart 5010/tcp # TelepathStart -telelpathattack 5011/udp # TelepathAttack -telelpathattack 5011/tcp # TelepathAttack -# Helmuth Breitenfellner -# 5012-5019 Unassigned -zenginkyo-1 5020/udp # zenginkyo-1 -zenginkyo-1 5020/tcp # zenginkyo-1 -zenginkyo-2 5021/udp # zenginkyo-2 -zenginkyo-2 5021/tcp # zenginkyo-2 -# Masashi Suzaki -mice 5022/udp # mice server -mice 5022/tcp # mice server -# Alan Clifford -htuilsrv 5023/udp # Htuil Server for PLD2 -htuilsrv 5023/tcp # Htuil Server for PLD2 -# Dennis Reinhardt -scpi-telnet 5024/udp # SCPI-TELNET -scpi-telnet 5024/tcp # SCPI-TELNET -scpi-raw 5025/udp # SCPI-RAW -scpi-raw 5025/tcp # SCPI-RAW -# Ryan Columbus October 2002 -# 5026-5041 Unassigned -asnaacceler8db 5042/udp # asnaacceler8db -asnaacceler8db 5042/tcp # asnaacceler8db -# Walter Goodwin -# 5043-5049 Unassigned -mmcc 5050/udp # multimedia conference control tool -mmcc 5050/tcp # multimedia conference control tool -# Steve Casner -ita-agent 5051/udp # ITA Agent -ita-agent 5051/tcp # ITA Agent -ita-manager 5052/udp # ITA Manager -ita-manager 5052/tcp # ITA Manager -# Don Merrell -# 5053-5054 Unassigned -unot 5055/udp # UNOT -unot 5055/tcp # UNOT -# Gordon Mohr -intecom-ps1 5056/udp # Intecom PS 1 -intecom-ps1 5056/tcp # Intecom PS 1 -intecom-ps2 5057/udp # Intecom PS 2 -intecom-ps2 5057/tcp # Intecom PS 2 -# David Meermans -# 5058-5059 Unassigned -sip 5060/udp # SIP -sip 5060/tcp # SIP -sip-tls 5061/udp # SIP-TLS -sip-tls 5061/tcp # SIP-TLS -# Henning Schulzrinne -# 5062-5063 Unassigned -ca-1 5064/udp # Channel Access 1 -ca-1 5064/tcp # Channel Access 1 -ca-2 5065/udp # Channel Access 2 -ca-2 5065/tcp # Channel Access 2 -# Jeffrey Hill August 2002 -# 5066-5067 Unassigned -stanag-5066 5066/udp # STANAG-5066-SUBNET-INTF -stanag-5066 5066/tcp # STANAG-5066-SUBNET-INTF -# Donald G. Kallgren -# -# 5062-5068 Unassigned -i-net-2000-npr 5069/udp # I/Net 2000-NPR -i-net-2000-npr 5069/tcp # I/Net 2000-NPR -# Kenny Garrison -# 5070 Unassigned -powerschool 5071/udp # PowerSchool -powerschool 5071/tcp # PowerSchool -# Greg Porter -# 5072-5080 Unassigned -sdl-ets 5081/udp # SDL - Ent Trans Server -sdl-ets 5081/tcp # SDL - Ent Trans Server -# Marc Morin April 2002 -# 5082-5092 Unassigned -sentinel-lm 5093/udp # Sentinel LM -sentinel-lm 5093/tcp # Sentinel LM -# Derick Snyder -# 5094-5098 Unassigned -sentlm-srv2srv 5099/udp # SentLM Srv2Srv -sentlm-srv2srv 5099/tcp # SentLM Srv2Srv -# Derick Snyder -# 5100 Unassigned -talarian-udp 5101/udp # Talarian_UDP -talarian-tcp 5101/tcp # Talarian_TCP -# Leo Martins -# 5102-5136 Unassigned -ctsd 5137/udp # MyCTS server port -ctsd 5137/tcp # MyCTS server port -# Jilles Oldenbeuving June 2002 -# 5138-5144 Unassigned -rmonitor_secure 5145/udp # RMONITOR SECURE -rmonitor_secure 5145/tcp # RMONITOR SECURE -# Kory Hamzeh -# 5146-5149 Unassigned -atmp 5150/udp # Ascend Tunnel Management Protocol -atmp 5150/tcp # Ascend Tunnel Management Protocol -# Kory Hamzeh -esri_sde 5151/udp # ESRI SDE Remote Start -esri_sde 5151/tcp # ESRI SDE Instance -sde-discovery 5152/udp # ESRI SDE Instance Discovery -sde-discovery 5152/tcp # ESRI SDE Instance Discovery -# Peter Aronson -# 5153-5164 Unassigned -ife_icorp 5165/udp # ife_1corp -ife_icorp 5165/tcp # ife_1corp -# Paul Annala -# 5166-5189 Unassigned -aol 5190/udp # America-Online -aol 5190/tcp # America-Online -# Marty Lyons -aol-1 5191/udp # AmericaOnline1 -aol-1 5191/tcp # AmericaOnline1 -aol-2 5192/udp # AmericaOnline2 -aol-2 5192/tcp # AmericaOnline2 -aol-3 5193/udp # AmericaOnline3 -aol-3 5193/tcp # AmericaOnline3 -# Bruce Mackey -# 5194-5199 Unassigned -targus-getdata 5200/udp # TARGUS GetData -targus-getdata 5200/tcp # TARGUS GetData -targus-getdata1 5201/udp # TARGUS GetData 1 -targus-getdata1 5201/tcp # TARGUS GetData 1 -targus-getdata2 5202/udp # TARGUS GetData 2 -targus-getdata2 5202/tcp # TARGUS GetData 2 -targus-getdata3 5203/udp # TARGUS GetData 3 -targus-getdata3 5203/tcp # TARGUS GetData 3 -# John Keaveney -# 5204-5221 Unassigned -jabber-client 5222/udp # Jabber Client Connection -jabber-client 5222/tcp # Jabber Client Connection -# David Waite February 2002 -# 5223-5224 Unassigned -hp-server 5225/udp # HP Server -hp-server 5225/tcp # HP Server -hp-status 5226/udp # HP Status -hp-status 5226/tcp # HP Status -# Brett Green -# 5227-5235 Unassigned -padl2sim 5236/udp # -padl2sim 5236/tcp # -# 5237-5249 Unassigned -igateway 5250/udp # iGateway -igateway 5250/tcp # iGateway -# Greg Bodine February 2002 -# 5251-5263 Unassigned -3com-njack-1 5264/udp # 3Com Network Jack Port 1 -3com-njack-1 5264/tcp # 3Com Network Jack Port 1 -3com-njack-2 5265/udp # 3Com Network Jack Port 2 -3com-njack-2 5265/tcp # 3Com Network Jack Port 2 -# Abhay Rajaram March 2003 -# 5266-5268 Unassigned -jabber-server 5269/udp # Jabber Server Connection -jabber-server 5269/tcp # Jabber Server Connection -# David Waite February 2002 -# 5270-5271 Unassigned -pk 5272/udp # PK -pk 5272/tcp # PK -# Patrick Kara -# 5273-5281 Unassigned -transmit-port 5282/udp # Marimba Transmitter Port -transmit-port 5282/tcp # Marimba Transmitter Port -# Johan Eriksson April 2002 -# 5283-5299 Unassigned -hacl-hb 5300/udp # # HA cluster heartbeat -hacl-hb 5300/tcp # # HA cluster heartbeat -hacl-gs 5301/udp # # HA cluster general services -hacl-gs 5301/tcp # # HA cluster general services -hacl-cfg 5302/udp # # HA cluster configuration -hacl-cfg 5302/tcp # # HA cluster configuration -hacl-probe 5303/udp # # HA cluster probing -hacl-probe 5303/tcp # # HA cluster probing -hacl-local 5304/udp # -hacl-local 5304/tcp # # HA Cluster Commands -hacl-test 5305/udp # -hacl-test 5305/tcp # # HA Cluster Test -# Eric Soderberg -# Edward Yim -sun-mc-grp 5306/udp # Sun MC Group -sun-mc-grp 5306/tcp # Sun MC Group -# Michael DeMoney -sco-aip 5307/udp # SCO AIP -sco-aip 5307/tcp # SCO AIP -# Barrie Cooper -cfengine 5308/udp # CFengine -cfengine 5308/tcp # CFengine -# Mark Burgess -jprinter 5309/udp # J Printer -jprinter 5309/tcp # J Printer -# Ken Blackwell -outlaws 5310/udp # Outlaws -outlaws 5310/tcp # Outlaws -# Richard Fife -tmlogin 5311/udp # TM Login -tmlogin 5311/tcp # TM Login -# Eric Sharakan -# 5312-5313 Unassigned -opalis-rbt-ipc 5314/udp # opalis-rbt-ipc -opalis-rbt-ipc 5314/tcp # opalis-rbt-ipc -# Laurent Domenech -hacl-poll 5315/udp # HA Cluster UDP Polling -hacl-poll 5315/tcp # HA Cluster UDP Polling -# Hoa Nguyen -# 5316-5352 Unassigned -mdns 5353/udp # Multicast DNS -mdns 5353/tcp # Multicast DNS -# Stuart Cheshire -# 5354-5399 Unassigned -excerpt 5400/udp # Excerpt Search -excerpt 5400/tcp # Excerpt Search -excerpts 5401/udp # Excerpt Search Secure -excerpts 5401/tcp # Excerpt Search Secure -# John Hinsdale -mftp 5402/udp # MFTP -mftp 5402/tcp # MFTP -# Alan Rosenberg -hpoms-ci-lstn 5403/udp # HPOMS-CI-LSTN -hpoms-ci-lstn 5403/tcp # HPOMS-CI-LSTN -hpoms-dps-lstn 5404/udp # HPOMS-DPS-LSTN -hpoms-dps-lstn 5404/tcp # HPOMS-DPS-LSTN -# Harold Froehling -netsupport 5405/udp # NetSupport -netsupport 5405/tcp # NetSupport -# Paul Sanders -systemics-sox 5406/udp # Systemics Sox -systemics-sox 5406/tcp # Systemics Sox -# Gary Howland -foresyte-clear 5407/udp # Foresyte-Clear -foresyte-clear 5407/tcp # Foresyte-Clear -foresyte-sec 5408/udp # Foresyte-Sec -foresyte-sec 5408/tcp # Foresyte-Sec -# Jorge Aldana -salient-dtasrv 5409/udp # Salient Data Server -salient-dtasrv 5409/tcp # Salient Data Server -salient-usrmgr 5410/udp # Salient User Manager -salient-usrmgr 5410/tcp # Salient User Manager -# Richard Farnham -actnet 5411/udp # ActNet -actnet 5411/tcp # ActNet -# Simon Robillard -continuus 5412/udp # Continuus -continuus 5412/tcp # Continuus -# Steven Holtsberg -wwiotalk 5413/udp # WWIOTALK -wwiotalk 5413/tcp # WWIOTALK -# Roger Knobbe -statusd 5414/udp # StatusD -statusd 5414/tcp # StatusD -# Stephen Misel -ns-server 5415/udp # NS Server -ns-server 5415/tcp # NS Server -# Jeffrey Chiao -sns-gateway 5416/udp # SNS Gateway -sns-gateway 5416/tcp # SNS Gateway -sns-agent 5417/udp # SNS Agent -sns-agent 5417/tcp # SNS Agent -# Mary Holstage -mcntp 5418/udp # MCNTP -mcntp 5418/tcp # MCNTP -# Heiko Rupp -dj-ice 5419/udp # DJ-ICE -dj-ice 5419/tcp # DJ-ICE -# Don Tyson -cylink-c 5420/udp # Cylink-C -cylink-c 5420/tcp # Cylink-C -# John Jobe -netsupport2 5421/udp # Net Support 2 -netsupport2 5421/tcp # Net Support 2 -# Paul Sanders -salient-mux 5422/udp # Salient MUX -salient-mux 5422/tcp # Salient MUX -# Richard Farnham -virtualuser 5423/udp # VIRTUALUSER -virtualuser 5423/tcp # VIRTUALUSER -# Chad Williams -# 5424-5425 Unassigned -devbasic 5426/udp # DEVBASIC -devbasic 5426/tcp # DEVBASIC -# Curtis Smith -sco-peer-tta 5427/udp # SCO-PEER-TTA -sco-peer-tta 5427/tcp # SCO-PEER-TTA -# Andrew Shire -telaconsole 5428/udp # TELACONSOLE -telaconsole 5428/tcp # TELACONSOLE -# Joseph M. Newcomer -base 5429/udp # Billing and Accounting System Exchange -base 5429/tcp # Billing and Accounting System Exchange -# Odo Maletzki -radec-corp 5430/udp # RADEC CORP -radec-corp 5430/tcp # RADEC CORP -# David Chell -park-agent 5431/udp # PARK AGENT -park-agent 5431/tcp # PARK AGENT -# John Clifford -postgresql 5432/udp # PostgreSQL Database -postgresql 5432/tcp # PostgreSQL Database -# Tom Lane -# 5433-5434 Unassigned -dttl 5435/udp # Data Tunneling Transceiver Linking (DTTL) -dttl 5435/tcp # Data Tunneling Transceiver Linking (DTTL) -# Richard Olsen -# 5436-5453 Unassigned -apc-5454 5454/udp # APC 5454 -apc-5454 5454/tcp # APC 5454 -apc-5455 5455/udp # APC 5455 -apc-5455 5455/tcp # APC 5455 -apc-5456 5456/udp # APC 5456 -apc-5456 5456/tcp # APC 5456 -# American Power Conversion -# 5457-5460 Unassigned -silkmeter 5461/udp # SILKMETER -silkmeter 5461/tcp # SILKMETER -# Alexander Kotopoulis -ttl-publisher 5462/udp # TTL Publisher -ttl-publisher 5462/tcp # TTL Publisher -# Peter Jacobs -ttlpriceproxy 5463/udp # TTL Price Proxy -ttlpriceproxy 5463/tcp # TTL Price Proxy -# Peter Jacobs -# 5464 Unassigned -netops-broker 5465/udp # NETOPS-BROKER -netops-broker 5465/tcp # NETOPS-BROKER -# John R. Deuel -# 5466-5499 Unassigned -fcp-addr-srvr1 5500/udp # fcp-addr-srvr1 -fcp-addr-srvr1 5500/tcp # fcp-addr-srvr1 -fcp-addr-srvr2 5501/udp # fcp-addr-srvr2 -fcp-addr-srvr2 5501/tcp # fcp-addr-srvr2 -fcp-srvr-inst1 5502/udp # fcp-srvr-inst1 -fcp-srvr-inst1 5502/tcp # fcp-srvr-inst1 -fcp-srvr-inst2 5503/udp # fcp-srvr-inst2 -fcp-srvr-inst2 5503/tcp # fcp-srvr-inst2 -fcp-cics-gw1 5504/udp # fcp-cics-gw1 -fcp-cics-gw1 5504/tcp # fcp-cics-gw1 -# Mark Zeiss -# 5505-5552 Unassigned -sgi-eventmond 5553/udp # SGI Eventmond Port -sgi-eventmond 5553/tcp # SGI Eventmond Port -# Andrei Vilkotski June 2003 -sgi-esphttp 5554/udp # SGI ESP HTTP -sgi-esphttp 5554/tcp # SGI ESP HTTP -# Vladimir Legalov -############Port 5555 also used by HP Omniback##################### -personal-agent 5555/udp # Personal Agent -personal-agent 5555/tcp # Personal Agent -# Jackie Wu -################################################################### -# 5556-5565 Unassigned -udpplus 5566/udp # UDPPlus -udpplus 5566/tcp # UDPPlus -# Cody Gibson -# 5567-5598 Unassigned -esinstall 5599/udp # Enterprise Security Remote Install -esinstall 5599/tcp # Enterprise Security Remote Install -esmmanager 5600/udp # Enterprise Security Manager -esmmanager 5600/tcp # Enterprise Security Manager -esmagent 5601/udp # Enterprise Security Agent -esmagent 5601/tcp # Enterprise Security Agent -# Kimberly Gibbs -a1-msc 5602/udp # A1-MSC -a1-msc 5602/tcp # A1-MSC -a1-bs 5603/udp # A1-BS -a1-bs 5603/tcp # A1-BS -a3-sdunode 5604/udp # A3-SDUNode -a3-sdunode 5604/tcp # A3-SDUNode -a4-sdunode 5605/udp # A4-SDUNode -a4-sdunode 5605/tcp # A4-SDUNode -# Mike Dolan -# 5606-5630 Unassigned -pcanywheredata 5631/udp # pcANYWHEREdata -pcanywheredata 5631/tcp # pcANYWHEREdata -pcanywherestat 5632/udp # pcANYWHEREstat -pcanywherestat 5632/tcp # pcANYWHEREstat -# Jon Rosarky -# 5633-5672 Unassigned -jms 5673/udp # JACL Message Server -jms 5673/tcp # JACL Message Server -# Stuart Allen February 2002 -hyperscsi-port 5674/udp # HyperSCSI Port -hyperscsi-port 5674/tcp # HyperSCSI Port -# Data Storage Institute, Singapore -# February 2002 -v5ua 5675/udp # V5UA application port -v5ua 5675/tcp # V5UA application port -# Sanjay Rao February 2002 -raadmin 5676/udp # RA Administration -raadmin 5676/tcp # RA Administration -# Sergei Zjaikin February 2002 -questdb2-lnchr 5677/udp # Quest Central DB2 Launchr -questdb2-lnchr 5677/tcp # Quest Central DB2 Launchr -# Robert M. Mackowiak February 2002 -rrac 5678/udp # Remote Replication Agent Connection -rrac 5678/tcp # Remote Replication Agent Connection -dccm 5679/udp # Direct Cable Connect Manager -dccm 5679/tcp # Direct Cable Connect Manager -# Mark Miller -# 5680-5687 Unassigned -ggz 5688/udp # GGZ Gaming Zone -ggz 5688/tcp # GGZ Gaming Zone -# Josef Spillner January 2003 -# 5689-5712 Unassigned -proshareaudio 5713/udp # proshare conf audio -proshareaudio 5713/tcp # proshare conf audio -prosharevideo 5714/udp # proshare conf video -prosharevideo 5714/tcp # proshare conf video -prosharedata 5715/udp # proshare conf data -prosharedata 5715/tcp # proshare conf data -prosharerequest 5716/udp # proshare conf request -prosharerequest 5716/tcp # proshare conf request -prosharenotify 5717/udp # proshare conf notify -prosharenotify 5717/tcp # proshare conf notify -# -# 5718-5719 Unassigned -ms-licensing 5720/udp # MS-Licensing -ms-licensing 5720/tcp # MS-Licensing -# Thomas Lindeman November 2002 -# 5721-5728 Unassigned -openmail 5729/udp # Openmail User Agent Layer -openmail 5729/tcp # Openmail User Agent Layer -# OpenMail Encyclopedia -# Don Loughry -unieng 5730/udp # Steltor's calendar access -unieng 5730/tcp # Steltor's calendar access -# Bernard Desruisseaux -# 5731-5740 Unassigned -ida-discover1 5741/udp # IDA Discover Port 1 -ida-discover1 5741/tcp # IDA Discover Port 1 -ida-discover2 5742/udp # IDA Discover Port 2 -ida-discover2 5742/tcp # IDA Discover Port 2 -# MPITech Support -# 5743-5744 Unassigned -fcopy-server 5745/udp # fcopy-server -fcopy-server 5745/tcp # fcopy-server -fcopys-server 5746/udp # fcopys-server -fcopys-server 5746/tcp # fcopys-server -# Moshe Leibovitch opencyc@hpopd.pwd.hp.com> -# Don Loughry -# 5769-5770 Unassigned -netagent 5771/udp # NetAgent -netagent 5771/tcp # NetAgent -# Bradley Birnbaum -# 5772-5812 Unassigned -icmpd 5813/udp # ICMPD -icmpd 5813/tcp # ICMPD -# Shane O'Donnell -# 5814-5858 Unassigned -wherehoo 5859/udp # WHEREHOO -wherehoo 5859/tcp # WHEREHOO -# Jim Youll -# 5860-5967 Unassigned -mppolicy-v5 5968/udp # mppolicy-v5 -mppolicy-v5 5968/tcp # mppolicy-v5 -mppolicy-mgr 5969/udp # mppolicy-mgr -mppolicy-mgr 5969/tcp # mppolicy-mgr -# Yutaka Ono -# 5970-5986 Unassigned -wbem-rmi 5987/udp # WBEM RMI -wbem-rmi 5987/tcp # WBEM RMI -wbem-http 5988/udp # WBEM HTTP -wbem-http 5988/tcp # WBEM HTTP -# Jim Davis -wbem-https 5989/udp # WBEM HTTPS -wbem-https 5989/tcp # WBEM HTTPS -# Jim Davis -# 5990 Unassigned (Removed 2003-02-26) -nuxsl 5991/udp # NUXSL -nuxsl 5991/tcp # NUXSL -# Kai Kretschmann March 2002 -# 5992-5998 Unassigned -cvsup 5999/udp # CVSup -cvsup 5999/tcp # CVSup -# Randall Atkinson -# Stephen Gildea -ndl-ahp-svc 6064/udp # NDL-AHP-SVC -ndl-ahp-svc 6064/tcp # NDL-AHP-SVC -# John Richmond -winpharaoh 6065/udp # WinPharaoh -winpharaoh 6065/tcp # WinPharaoh -# Basil Lee -ewctsp 6066/udp # EWCTSP -ewctsp 6066/tcp # EWCTSP -# Mark Bailon -srb 6067/udp # SRB -srb 6067/tcp # SRB -# Heinz Naef -gsmp 6068/udp # GSMP -gsmp 6068/tcp # GSMP -# Avri Doria -trip 6069/udp # TRIP -trip 6069/tcp # TRIP -# Hussein F. Salama -messageasap 6070/udp # Messageasap -messageasap 6070/tcp # Messageasap -# Murray Freeman -ssdtp 6071/udp # SSDTP -ssdtp 6071/tcp # SSDTP -# Michael Shearson -diagnose-proc 6072/udp # DIAGNOSE-PROC -diagnose-proc 6072/tcp # DIAGNOSE-PROC -# Allan Miller -directplay8 6073/udp # DirectPlay8 -directplay8 6073/tcp # DirectPlay8 -# John Kane -# 6074-6084 Unassigned -konspire2b 6085/udp # konspire2b p2p network -konspire2b 6085/tcp # konspire2b p2p network -# Jason Rohrer October 2002 -# 6086-6099 Unassigned -synchronet-db 6100/udp # SynchroNet-db -synchronet-db 6100/tcp # SynchroNet-db -synchronet-rtc 6101/udp # SynchroNet-rtc -synchronet-rtc 6101/tcp # SynchroNet-rtc -synchronet-upd 6102/udp # SynchroNet-upd -synchronet-upd 6102/tcp # SynchroNet-upd -# Arne Haugland -rets 6103/udp # RETS -rets 6103/tcp # RETS -# Bruce Toback -dbdb 6104/udp # DBDB -dbdb 6104/tcp # DBDB -# Aaron Brick -primaserver 6105/udp # Prima Server -primaserver 6105/tcp # Prima Server -mpsserver 6106/udp # MPS Server -mpsserver 6106/tcp # MPS Server -# Prima Designs Systems Ltd. -etc-control 6107/udp # ETC Control -etc-control 6107/tcp # ETC Control -# Steve Polishinski -sercomm-scadmin 6108/udp # Sercomm-SCAdmin -sercomm-scadmin 6108/tcp # Sercomm-SCAdmin -# Melinda Tsao -globecast-id 6109/udp # GLOBECAST-ID -globecast-id 6109/tcp # GLOBECAST-ID -# Piers Scannell -softcm 6110/udp # HP SoftBench CM -softcm 6110/tcp # HP SoftBench CM -spc 6111/udp # HP SoftBench Sub-Process Control -spc 6111/tcp # HP SoftBench Sub-Process Control -# Scott A. Kramer -dtspcd 6112/udp # dtspcd -dtspcd 6112/tcp # dtspcd -# Doug Royer -# 6113-6122 Unassigned -backup-express 6123/udp # Backup Express -backup-express 6123/tcp # Backup Express -# Chi Shih Chang -# 6124-6140 Unassigned -meta-corp 6141/udp # Meta Corporation License Manager -meta-corp 6141/tcp # Meta Corporation License Manager -# Osamu Masuda <--none---> -aspentec-lm 6142/udp # Aspen Technology License Manager -aspentec-lm 6142/tcp # Aspen Technology License Manager -# Kevin Massey -watershed-lm 6143/udp # Watershed License Manager -watershed-lm 6143/tcp # Watershed License Manager -# David Ferrero -statsci1-lm 6144/udp # StatSci License Manager - 1 -statsci1-lm 6144/tcp # StatSci License Manager - 1 -statsci2-lm 6145/udp # StatSci License Manager - 2 -statsci2-lm 6145/tcp # StatSci License Manager - 2 -# Scott Blachowicz -lonewolf-lm 6146/udp # Lone Wolf Systems License Manager -lonewolf-lm 6146/tcp # Lone Wolf Systems License Manager -# Dan Klein -montage-lm 6147/udp # Montage License Manager -montage-lm 6147/tcp # Montage License Manager -# Michael Ubell -ricardo-lm 6148/udp # Ricardo North America License Manager -ricardo-lm 6148/tcp # Ricardo North America License Manager -# M Flemming -tal-pod 6149/udp # tal-pod -tal-pod 6149/tcp # tal-pod -# Steven Loomis -# 6150-6252 Unassigned -crip 6253/udp # CRIP -crip 6253/tcp # CRIP -# Mike Rodbell -# 6254-6299 Unassigned -bmc-grx 6300/udp # BMC GRX -bmc-grx 6300/tcp # BMC GRX -# Ed Penak -# 6301-6320 Unassigned -emp-server1 6321/udp # Empress Software Connectivity Server 1 -emp-server1 6321/tcp # Empress Software Connectivity Server 1 -emp-server2 6322/udp # Empress Software Connectivity Server 2 -emp-server2 6322/tcp # Empress Software Connectivity Server 2 -# Srdjan Holovac -# 6323-6342 Unassigned -sflow 6343/udp # sFlow traffic monitoring -sflow 6343/tcp # sFlow traffic monitoring -# Peter Phaal June 2003 -# 6344-6345 Unassigned -gnutella-svc 6346/udp # gnutella-svc -gnutella-svc 6346/tcp # gnutella-svc -gnutella-rtr 6347/udp # gnutella-rtr -gnutella-rtr 6347/tcp # gnutella-rtr -# Serguei Osokine -# 6348-6381 Unassigned -metatude-mds 6382/udp # Metatude Dialogue Server -metatude-mds 6382/tcp # Metatude Dialogue Server -# Menno Zweistra -# 6383-6388 Unassigned -clariion-evr01 6389/udp # clariion-evr01 -clariion-evr01 6389/tcp # clariion-evr01 -# Dave DesRoches -# 6390-6399 Unassigned -# The following blocks are in use by Seagate Software 6400-6410 # -# The previous ports are in use by Seagate Software 6400-6410 # -# Contact for these ports is Wade Richards -# 6411-6454 Unassigned -skip-cert-recv 6455/tcp # SKIP Certificate Receive -skip-cert-send 6456/tcp # SKIP Certificate Send -# Tom Markson -# 6457-6470 Unassigned -lvision-lm 6471/udp # LVision License Manager -lvision-lm 6471/tcp # LVision License Manager -# Brian McKinnon -# 6472-6499 Unassigned -boks 6500/udp # BoKS Master -boks 6500/tcp # BoKS Master -boks_servc 6501/udp # BoKS Servc -boks_servc 6501/tcp # BoKS Servc -boks_servm 6502/udp # BoKS Servm -boks_servm 6502/tcp # BoKS Servm -boks_clntd 6503/udp # BoKS Clntd -boks_clntd 6503/tcp # BoKS Clntd -# Magnus Nystrom -# 6504 Unassigned -badm_priv 6505/udp # BoKS Admin Private Port -badm_priv 6505/tcp # BoKS Admin Private Port -badm_pub 6506/udp # BoKS Admin Public Port -badm_pub 6506/tcp # BoKS Admin Public Port -bdir_priv 6507/udp # BoKS Dir Server, Private Port -bdir_priv 6507/tcp # BoKS Dir Server, Private Port -bdir_pub 6508/udp # BoKS Dir Server, Public Port -bdir_pub 6508/tcp # BoKS Dir Server, Public Port -# Magnus Nystrom -mgcs-mfp-port 6509/udp # MGCS-MFP Port -mgcs-mfp-port 6509/tcp # MGCS-MFP Port -# Minoru Ozaki -mcer-port 6510/udp # MCER Port -mcer-port 6510/tcp # MCER Port -# Ade Adebayo -# 6511-6542 Unassigned -lds-distrib 6543/udp # lds_distrib -lds-distrib 6543/tcp # lds_distrib -# Jack Baker June 2003 -# 6544-6546 Unassigned -apc-6547 6547/udp # APC 6547 -apc-6547 6547/tcp # APC 6547 -apc-6548 6548/udp # APC 6548 -apc-6548 6548/tcp # APC 6548 -apc-6549 6549/udp # APC 6549 -apc-6549 6549/tcp # APC 6549 -# American Power Conversion -fg-sysupdate 6550/udp # fg-sysupdate -fg-sysupdate 6550/tcp # fg-sysupdate -# Mark Beyer -# 6551-6557 Unassigned -xdsxdm 6558/udp # -xdsxdm 6558/tcp # -# Brian Tackett possible contact -# 6559-6565 Unassigned -sane-port 6566/udp # SANE Control Port -sane-port 6566/tcp # SANE Control Port -# Henning Meier-Geinitz October 2002 -# 6567-6579 Unassigned -parsec-master 6580/udp # Parsec Masterserver -parsec-master 6580/tcp # Parsec Masterserver -parsec-peer 6581/udp # Parsec Peer-to-Peer -parsec-peer 6581/tcp # Parsec Peer-to-Peer -parsec-game 6582/udp # Parsec Gameserver -parsec-game 6582/tcp # Parsec Gameserver -# Andreas Varga -# 6583-6587 Unassigned -# 6588 Unassigned -####Unofficial use of port 6588 by AnalogX and Microsoft#### -# 6589-6627 Unassigned -afesc-mc 6628/udp # AFE Stock Channel M/C -afesc-mc 6628/tcp # AFE Stock Channel M/C -# Timothy Tam March 2003 -# 6629-6630 Unassigned -mach 6631/udp # Mitchell telecom host -mach 6631/tcp # Mitchell telecom host -# Mark Derail March 2003 -# 6632-6664 Unassigned -# Brian Tackett -vocaltec-gold 6670/udp # Vocaltec Global Online Directory -vocaltec-gold 6670/tcp # Vocaltec Global Online Directory -# Scott Petrack -# 6671 Unassigned -vision_server 6672/udp # vision_server -vision_server 6672/tcp # vision_server -vision_elmd 6673/udp # vision_elmd -vision_elmd 6673/tcp # vision_elmd -# Chris Kramer -# 6674-6700 Unassigned -kti-icad-srvr 6701/udp # KTI/ICAD Nameserver -kti-icad-srvr 6701/tcp # KTI/ICAD Nameserver -# Stanley Knutson -# 6702-6713 Unassigned -ibprotocol 6714/udp # Internet Backplane Protocol -ibprotocol 6714/tcp # Internet Backplane Protocol -# Alessandro Bassi -# 6715-6766 Unassigned -bmc-perf-agent 6767/udp # BMC PERFORM AGENT -bmc-perf-agent 6767/tcp # BMC PERFORM AGENT -bmc-perf-mgrd 6768/udp # BMC PERFORM MGRD -bmc-perf-mgrd 6768/tcp # BMC PERFORM MGRD -# Dima Seliverstov -# 6769-6787 Unassigned -smc-http 6788/udp # SMC-HTTP -smc-http 6788/tcp # SMC-HTTP -# Ratnadeep Bhattacharjee November 2002 -smc-https 6789/udp # SMC-HTTPS -smc-https 6789/tcp # SMC-HTTPS -# Ratnadeep Bhattacharjee August 2002 -hnmp 6790/udp # HNMP -hnmp 6790/tcp # HNMP -# Jude George -# 6791-6830 Unassigned -ambit-lm 6831/udp # ambit-lm -ambit-lm 6831/tcp # ambit-lm -# Don Hejna -# 6832-6840 Unassigned -netmo-default 6841/udp # Netmo Default -netmo-default 6841/tcp # Netmo Default -netmo-http 6842/udp # Netmo HTTP -netmo-http 6842/tcp # Netmo HTTP -# Urs Bertschinger -# 6843-6849 Unassigned -iccrushmore 6850/udp # ICCRUSHMORE -iccrushmore 6850/tcp # ICCRUSHMORE -# Dave Hubbard -# 6851-6887 Unassigned -muse 6888/udp # MUSE -muse 6888/tcp # MUSE -# Muse Communications Corporation -# -# 6889-6960 Unassigned -jmact3 6961/udp # JMACT3 -jmact3 6961/tcp # JMACT3 -jmevt2 6962/udp # jmevt2 -jmevt2 6962/tcp # jmevt2 -swismgr1 6963/udp # swismgr1 -swismgr1 6963/tcp # swismgr1 -swismgr2 6964/udp # swismgr2 -swismgr2 6964/tcp # swismgr2 -swistrap 6965/udp # swistrap -swistrap 6965/tcp # swistrap -swispol 6966/udp # swispol -swispol 6966/tcp # swispol -# Yutaka Ono -# 6967-6968 Unassigned -acmsoda 6969/udp # acmsoda -acmsoda 6969/tcp # acmsoda -# Daniel Simms -# 6970-6997 Unassigned -iatp-highpri 6998/udp # IATP-highPri -iatp-highpri 6998/tcp # IATP-highPri -iatp-normalpri 6999/udp # IATP-normalPri -iatp-normalpri 6999/tcp # IATP-normalPri -# John Murphy -afs3-fileserver 7000/udp # file server itself -afs3-fileserver 7000/tcp # file server itself -afs3-callback 7001/udp # callbacks to cache managers -afs3-callback 7001/tcp # callbacks to cache managers -afs3-prserver 7002/udp # users & groups database -afs3-prserver 7002/tcp # users & groups database -afs3-vlserver 7003/udp # volume location database -afs3-vlserver 7003/tcp # volume location database -afs3-kaserver 7004/udp # AFS/Kerberos authentication service -afs3-kaserver 7004/tcp # AFS/Kerberos authentication service -afs3-volser 7005/udp # volume managment server -afs3-volser 7005/tcp # volume managment server -afs3-errors 7006/udp # error interpretation service -afs3-errors 7006/tcp # error interpretation service -afs3-bos 7007/udp # basic overseer process -afs3-bos 7007/tcp # basic overseer process -afs3-update 7008/udp # server-to-server updater -afs3-update 7008/tcp # server-to-server updater -afs3-rmtsys 7009/udp # remote cache manager service -afs3-rmtsys 7009/tcp # remote cache manager service -# -ups-onlinet 7010/udp # onlinet uninterruptable power supplies -ups-onlinet 7010/tcp # onlinet uninterruptable power supplies -# Brian Hammill -talon-disc 7011/udp # Talon Discovery Port -talon-disc 7011/tcp # Talon Discovery Port -talon-engine 7012/udp # Talon Engine -talon-engine 7012/tcp # Talon Engine -microtalon-dis 7013/udp # Microtalon Discovery -microtalon-dis 7013/tcp # Microtalon Discovery -microtalon-com 7014/udp # Microtalon Communications -microtalon-com 7014/tcp # Microtalon Communications -talon-webserver 7015/udp # Talon Webserver -talon-webserver 7015/tcp # Talon Webserver -# Jack Curtin -# 7016-7019 Unassigned -dpserve 7020/udp # DP Serve -dpserve 7020/tcp # DP Serve -dpserveadmin 7021/udp # DP Serve Admin -dpserveadmin 7021/tcp # DP Serve Admin -# Allan Stanley -# 7022-7029 Unassigned -op-probe 7030/udp # ObjectPlanet probe -op-probe 7030/tcp # ObjectPlanet probe -# Bjorn Jarle Kvande April 2002 -# 7031-7069 Unassigned -arcp 7070/udp # ARCP -arcp 7070/tcp # ARCP -# Jude George -# 7071-7098 Unassigned -lazy-ptop 7099/udp # lazy-ptop -lazy-ptop 7099/tcp # lazy-ptop -# Guy Keren -font-service 7100/udp # X Font Service -font-service 7100/tcp # X Font Service -# Stephen Gildea -# 7101-7120 Unassigned -virprot-lm 7121/udp # Virtual Prototypes License Manager -virprot-lm 7121/tcp # Virtual Prototypes License Manager -# Victor Galis -# 7122-7173 Unassigned -clutild 7174/udp # Clutild -clutild 7174/tcp # Clutild -# Cheryl Stoutenburg -# 7175-7199 Unassigned -fodms 7200/udp # FODMS FLIP -fodms 7200/tcp # FODMS FLIP -# David Anthony -dlip 7201/udp # DLIP -dlip 7201/tcp # DLIP -# Albert Manfredi -# 7202-7279 Unassigned -itactionserver1 7280/udp # ITACTIONSERVER 1 -itactionserver1 7280/tcp # ITACTIONSERVER 1 -itactionserver2 7281/udp # ITACTIONSERVER 2 -itactionserver2 7281/tcp # ITACTIONSERVER 2 -# Brian Taylor -# 7282-7299 Unassigned -# Edgar Blum -mindfilesys 7391/udp # mind-file system server -mindfilesys 7391/tcp # mind-file system server -mrssrendezvous 7392/udp # mrss-rendezvous server -mrssrendezvous 7392/tcp # mrss-rendezvous server -# Dave Porter -# 7393-7394 Unassigned -winqedit 7395/udp # winqedit -winqedit 7395/tcp # winqedit -# David Greer -# 7396-7425 Unassigned -pmdmgr 7426/udp # OpenView DM Postmaster Manager -pmdmgr 7426/tcp # OpenView DM Postmaster Manager -oveadmgr 7427/udp # OpenView DM Event Agent Manager -oveadmgr 7427/tcp # OpenView DM Event Agent Manager -ovladmgr 7428/udp # OpenView DM Log Agent Manager -ovladmgr 7428/tcp # OpenView DM Log Agent Manager -opi-sock 7429/udp # OpenView DM rqt communication -opi-sock 7429/tcp # OpenView DM rqt communication -xmpv7 7430/udp # OpenView DM xmpv7 api pipe -xmpv7 7430/tcp # OpenView DM xmpv7 api pipe -pmd 7431/udp # OpenView DM ovc/xmpv3 api pipe -pmd 7431/tcp # OpenView DM ovc/xmpv3 api pipe -# Dave Lamb -faximum 7437/udp # Faximum -faximum 7437/tcp # Faximum -# George Pajari -# 7438-7490 Unassigned -telops-lmd 7491/udp # telops-lmd -telops-lmd 7491/tcp # telops-lmd -# David Spencer -# 7492-7499 Unassigned -# 7500 Unassigned -ovbus 7501/udp # HP OpenView Bus Daemon -ovbus 7501/tcp # HP OpenView Bus Daemon -# David M. Rhodes -# 7502-7509 Unassigned -ovhpas 7510/udp # HP OpenView Application Server -ovhpas 7510/tcp # HP OpenView Application Server -# Jeff Conrad -pafec-lm 7511/udp # pafec-lm -pafec-lm 7511/tcp # pafec-lm -# Billy Dhillon -# 7512-7543 Unassigned -nta-ds 7544/udp # FlowAnalyzer DisplayServer -nta-ds 7544/tcp # FlowAnalyzer DisplayServer -nta-us 7545/udp # FlowAnalyzer UtilityServer -nta-us 7545/tcp # FlowAnalyzer UtilityServer -# Fred Messinger -# 7546-7565 Unassigned -vsi-omega 7566/udp # VSI Omega -vsi-omega 7566/tcp # VSI Omega -# Curtis Smith -# 7567-7569 Unassigned -aries-kfinder 7570/udp # Aries Kfinder -aries-kfinder 7570/tcp # Aries Kfinder -# James King, III -# 7571-7587 Unassigned -sun-lm 7588/udp # Sun License Manager -sun-lm 7588/tcp # Sun License Manager -# Sophie Deng -# 7589-7623 Unassigned -indi 7624/udp # Instrument Neutral Distributed Interface -indi 7624/tcp # Instrument Neutral Distributed Interface -# Elwood Downey April 2002 -# 7625-7632 Unassigned -pmdfmgt 7633/udp # PMDF Management -pmdfmgt 7633/tcp # PMDF Management -# Hunter Goatley -# 7634-7673 Unassigned -imqtunnels 7674/udp # iMQ SSL tunnel -imqtunnels 7674/tcp # iMQ SSL tunnel -imqtunnel 7675/udp # iMQ Tunnel -imqtunnel 7675/tcp # iMQ Tunnel -# Shailesh S. Bavadekar April 2002 -imqbrokerd 7676/udp # iMQ Broker Rendezvous -imqbrokerd 7676/tcp # iMQ Broker Rendezvous -# Joseph Di Pol April 2002 -# 7677-7742 Unassigned -sstp-1 7743/udp # Sakura Script Transfer Protocol -sstp-1 7743/tcp # Sakura Script Transfer Protocol -# Kouichi Takeda -# 7744-7776 Unassigned -cbt 7777/udp # cbt -cbt 7777/tcp # cbt -# Tony Ballardie -interwise 7778/udp # Interwise -interwise 7778/tcp # Interwise -# Joseph Gray -vstat 7779/udp # VSTAT -vstat 7779/tcp # VSTAT -# Vinh Nguyn -# 7780 Unassigned -accu-lmgr 7781/udp # accu-lmgr -accu-lmgr 7781/tcp # accu-lmgr -# Moises E. Hernandez -# 7782-7785 Unassigned -minivend 7786/udp # MINIVEND -minivend 7786/tcp # MINIVEND -# Mike Heins -# 7787-7796 Unassigned -pnet-conn 7797/udp # Propel Connector port -pnet-conn 7797/tcp # Propel Connector port -pnet-enc 7798/udp # Propel Encoder port -pnet-enc 7798/tcp # Propel Encoder port -# Leif Hedstrom April 2002 -# 7799-7844 Unassigned -apc-7845 7845/udp # APC 7845 -apc-7845 7845/tcp # APC 7845 -apc-7846 7846/udp # APC 7846 -apc-7846 7846/tcp # APC 7846 -# American Power Conversion -# 7847-7912 Unassigned -qo-secure 7913/udp # QuickObjects secure port -qo-secure 7913/tcp # QuickObjects secure port -# Jonas Bovin -# 7914-7931 Unassigned -t2-drm 7932/udp # Tier 2 Data Resource Manager -t2-drm 7932/tcp # Tier 2 Data Resource Manager -t2-brm 7933/udp # Tier 2 Business Rules Manager -t2-brm 7933/tcp # Tier 2 Business Rules Manager -# Peter Carlson -# 7934-7966 Unassigned -supercell 7967/udp # Supercell -supercell 7967/tcp # Supercell -# Kevin Nakagawa -# 7968-7978 Unassigned -micromuse-ncps 7979/udp # Micromuse-ncps -micromuse-ncps 7979/tcp # Micromuse-ncps -# Hing Wing To -quest-vista 7980/udp # Quest Vista -quest-vista 7980/tcp # Quest Vista -# Preston Bannister -# 7981-7998 Unassigned -irdmi2 7999/udp # iRDMI2 -irdmi2 7999/tcp # iRDMI2 -irdmi 8000/udp # iRDMI -irdmi 8000/tcp # iRDMI -# Gil Shafriri -vcom-tunnel 8001/udp # VCOM Tunnel -vcom-tunnel 8001/tcp # VCOM Tunnel -# Mark Lewandowski -teradataordbms 8002/udp # Teradata ORDBMS -teradataordbms 8002/tcp # Teradata ORDBMS -# Curt Ellmann -# 8003-8007 Unassigned -http-alt 8008/udp # HTTP Alternate -http-alt 8008/tcp # HTTP Alternate -# James Gettys -# 8009-8021 Unassigned -oa-system 8022/udp # oa-system -oa-system 8022/tcp # oa-system -# Denis Girault -# 8023-8031 Unassigned -pro-ed 8032/udp # ProEd -pro-ed 8032/tcp # ProEd -mindprint 8033/udp # MindPrint -mindprint 8033/tcp # MindPrint -# Larry Tusoni -# 8034-8079 Unassigned -http-alt 8080/udp # HTTP Alternate (see port 80) -http-alt 8080/tcp # HTTP Alternate (see port 80) -# Stephen Casner -# 8081-8087 Unassigned -radan-http 8088/udp # Radan HTTP -radan-http 8088/tcp # Radan HTTP -# Steve Hay April 2002 -# 8089-8099 Unassigned -xprint-server 8100/udp # Xprint Server -xprint-server 8100/tcp # Xprint Server -# John McKernan -# 8101-8114 Unassigned -mtl8000-matrix 8115/udp # MTL8000 Matrix -mtl8000-matrix 8115/tcp # MTL8000 Matrix -# David Pinch April 2002 -cp-cluster 8116/udp # Check Point Clustering -cp-cluster 8116/tcp # Check Point Clustering -# Roni Moshitzky -# 8117 Unassigned -privoxy 8118/udp # Privoxy HTTP proxy -privoxy 8118/tcp # Privoxy HTTP proxy -# Andreas Oesterhelt June 2002 -# 8119-8129 Unassigned -indigo-vrmi 8130/udp # INDIGO-VRMI -indigo-vrmi 8130/tcp # INDIGO-VRMI -indigo-vbcp 8131/udp # INDIGO-VBCP -indigo-vbcp 8131/tcp # INDIGO-VBCP -# Colin Caughie -dbabble 8132/udp # dbabble -dbabble 8132/tcp # dbabble -# Chris Pugmire -# 8133-8159 Unassigned -patrol 8160/udp # Patrol -patrol 8160/tcp # Patrol -patrol-snmp 8161/udp # Patrol SNMP -patrol-snmp 8161/tcp # Patrol SNMP -# Daisy Tam -# 8162-8198 Unassigned -vvr-data 8199/udp # VVR DATA -vvr-data 8199/tcp # VVR DATA -# Ming Xu -trivnet1 8200/udp # TRIVNET -trivnet1 8200/tcp # TRIVNET -trivnet2 8201/udp # TRIVNET -trivnet2 8201/tcp # TRIVNET -# Saar Wilf -# 8202-8203 Unassigned -lm-perfworks 8204/udp # LM Perfworks -lm-perfworks 8204/tcp # LM Perfworks -lm-instmgr 8205/udp # LM Instmgr -lm-instmgr 8205/tcp # LM Instmgr -lm-dta 8206/udp # LM Dta -lm-dta 8206/tcp # LM Dta -lm-sserver 8207/udp # LM SServer -lm-sserver 8207/tcp # LM SServer -lm-webwatcher 8208/udp # LM Webwatcher -lm-webwatcher 8208/tcp # LM Webwatcher -# Chris Flynn -# 8209-8350 Unassigned -server-find 8351/udp # Server Find -server-find 8351/tcp # Server Find -# Chris Brown -# 8352-8375 Unassigned -cruise-enum 8376/udp # Cruise ENUM -cruise-enum 8376/tcp # Cruise ENUM -cruise-swroute 8377/udp # Cruise SWROUTE -cruise-swroute 8377/tcp # Cruise SWROUTE -cruise-config 8378/udp # Cruise CONFIG -cruise-config 8378/tcp # Cruise CONFIG -cruise-diags 8379/udp # Cruise DIAGS -cruise-diags 8379/tcp # Cruise DIAGS -cruise-update 8380/udp # Cruise UPDATE -cruise-update 8380/tcp # Cruise UPDATE -# Steve Husak -# 8381-8399 Unassigned -cvd 8400/udp # cvd -cvd 8400/tcp # cvd -sabarsd 8401/udp # sabarsd -sabarsd 8401/tcp # sabarsd -abarsd 8402/udp # abarsd -abarsd 8402/tcp # abarsd -admind 8403/udp # admind -admind 8403/tcp # admind -# Aaron Bilbrey -# 8404-8415 Unassigned -espeech 8416/udp # eSpeech Session Protocol -espeech 8416/tcp # eSpeech Session Protocol -# Scott Tarone November 2002 -espeech-rtp 8417/udp # eSpeech RTP Protocol -espeech-rtp 8417/tcp # eSpeech RTP Protocol -# Scott Tarone April 2003 -# 8418-8442 Unassigned -pcsync-https 8443/udp # PCsync HTTPS -pcsync-https 8443/tcp # PCsync HTTPS -pcsync-http 8444/udp # PCsync HTTP -pcsync-http 8444/tcp # PCsync HTTP -# Katy Lynn McCullough -# 8445-8449 Unassigned -npmp 8450/udp # npmp -npmp 8450/tcp # npmp -# Ian Chard -# 8451-8472 Unassigned -vp2p 8473/udp # Virtual Point to Point -vp2p 8473/tcp # Virtual Point to Point -# Jerome Grimbert -# 8474-8553 Unassigned -rtsp-alt 8554/udp # RTSP Alternate (see port 554) -rtsp-alt 8554/tcp # RTSP Alternate (see port 554) -# Stephen Casner -d-fence 8555/udp # SYMAX D-FENCE -d-fence 8555/tcp # SYMAX D-FENCE -# Thomas Geisel January 2003 -# 8556-8667 Unassigned -natd 8668/divert # Network Address Translation -# 8669-8732 Unassigned -ibus 8733/udp # iBus -ibus 8733/tcp # iBus -# Silvano Maffeis -# 8734-8762 Unassigned -mc-appserver 8763/udp # MC-APPSERVER -mc-appserver 8763/tcp # MC-APPSERVER -# Romeo Kasanwidjojo -openqueue 8764/udp # OPENQUEUE -openqueue 8764/tcp # OPENQUEUE -# Matt Jensen -ultraseek-http 8765/udp # Ultraseek HTTP -ultraseek-http 8765/tcp # Ultraseek HTTP -# Walter Underwood -# 8766-8785 Unassigned -msgclnt 8786/udp # Message Client -msgclnt 8786/tcp # Message Client -msgsrvr 8787/udp # Message Server -msgsrvr 8787/tcp # Message Server -# Michael O'Brien March 2003 -# 8788-8803 Unassigned -truecm 8804/udp # truecm -truecm 8804/tcp # truecm -# Scott Kramer -# 8805-8879 -cddbp-alt 8880/udp # CDDBP -cddbp-alt 8880/tcp # CDDBP -# Steve Scherf -# 8881-8887 Unassigned -ddi-udp-1 8888/udp # NewsEDGE server UDP (UDP 1) -ddi-tcp-1 8888/tcp # NewsEDGE server TCP (TCP 1) -ddi-udp-2 8889/udp # NewsEDGE server broadcast -ddi-tcp-2 8889/tcp # Desktop Data TCP 1 -ddi-udp-3 8890/udp # NewsEDGE client broadcast -ddi-tcp-3 8890/tcp # Desktop Data TCP 2 -ddi-udp-4 8891/udp # Desktop Data UDP 3: NESS application -ddi-tcp-4 8891/tcp # Desktop Data TCP 3: NESS application -ddi-udp-5 8892/udp # Desktop Data UDP 4: FARM product -ddi-tcp-5 8892/tcp # Desktop Data TCP 4: FARM product -ddi-udp-6 8893/udp # Desktop Data UDP 5: NewsEDGE/Web application -ddi-tcp-6 8893/tcp # Desktop Data TCP 5: NewsEDGE/Web application -ddi-udp-7 8894/udp # Desktop Data UDP 6: COAL application -ddi-tcp-7 8894/tcp # Desktop Data TCP 6: COAL application -# Fred Yao -# 8895-8899 Unassigned -jmb-cds1 8900/udp # JMB-CDS 1 -jmb-cds1 8900/tcp # JMB-CDS 1 -jmb-cds2 8901/udp # JMB-CDS 2 -jmb-cds2 8901/tcp # JMB-CDS 2 -# Curtis Bray -# 8902-8909 Unassigned -manyone-http 8910/udp # manyone-http -manyone-http 8910/tcp # manyone-http -manyone-xml 8911/udp # manyone-xml -manyone-xml 8911/tcp # manyone-xml -# Matt King April 2002 -# 8912-8953 Unassigned -cumulus-admin 8954/udp # Cumulus Admin Port -cumulus-admin 8954/tcp # Cumulus Admin Port -# Thomas Schleu -# 8955-8998 Unassigned -bctp 8999/udp # Brodos Crypto Trade Protocol -bctp 8999/tcp # Brodos Crypto Trade Protocol -# Alexander Sahler February 2002 -cslistener 9000/udp # CSlistener -cslistener 9000/tcp # CSlistener -# David Jones -etlservicemgr 9001/udp # ETL Service Manager -etlservicemgr 9001/tcp # ETL Service Manager -# Stephen McCrea March 2002 -dynamid 9002/udp # DynamID authentication -dynamid 9002/tcp # DynamID authentication -# Jerome Dusautois March 2002 -# 9003-9005 Unassigned -# 9006 De-Commissioned Port 02/24/00, ms -# 9007-9019 Unassigned -tambora 9020/udp # TAMBORA -tambora 9020/tcp # TAMBORA -# Jason van Zyl March 2002 -panagolin-ident 9021/udp # Pangolin Identification -panagolin-ident 9021/tcp # Pangolin Identification -# William Benner March 2002 -paragent 9022/udp # PrivateArk Remote Agent -paragent 9022/tcp # PrivateArk Remote Agent -# Gal Cucuy March 2002 -swa-1 9023/udp # Secure Web Access - 1 -swa-1 9023/tcp # Secure Web Access - 1 -swa-2 9024/udp # Secure Web Access - 2 -swa-2 9024/tcp # Secure Web Access - 2 -swa-3 9025/udp # Secure Web Access - 3 -swa-3 9025/tcp # Secure Web Access - 3 -swa-4 9026/udp # Secure Web Access - 4 -swa-4 9026/tcp # Secure Web Access - 4 -# Tim McGranaghan -# 9027-9079 Unassigned -glrpc 9080/udp # Groove GLRPC -glrpc 9080/tcp # Groove GLRPC -# Adrian Popescu September 2002 -# 9081-9089 Unassigned -websm 9090/udp # WebSM -websm 9090/tcp # WebSM -# I-Hsing Tsao -xmltec-xmlmail 9091/udp # xmltec-xmlmail -xmltec-xmlmail 9091/tcp # xmltec-xmlmail -# Mitch Kaufman -# 9092-9099 Unassigned -hp-pdl-datastr 9100/udp # PDL Data Streaming Port -hp-pdl-datastr 9100/tcp # PDL Data Streaming Port -# Shivaun Albright April 2002 -#### The protocol name "pdl-datastream" is primarily registered for use #### -#### in DNS SRV records (RFC 2782). DNS SRV records allow a protocol to run on #### -#### any port number, but the default port for this protocol is 9100 ####. -pdl-datastream 9100/udp # Printer PDL Data Stream -pdl-datastream 9100/tcp # Printer PDL Data Stream -bacula-dir 9101/udp # Bacula Director -bacula-dir 9101/tcp # Bacula Director -bacula-fd 9102/udp # Bacula File Daemon -bacula-fd 9102/tcp # Bacula File Daemon -bacula-sd 9103/udp # Bacula Storage Daemon -bacula-sd 9103/tcp # Bacula Storage Daemon -# Kern Sibbald January 2002 -# 9104-9159 Unassigned -netlock1 9160/udp # NetLOCK1 -netlock1 9160/tcp # NetLOCK1 -netlock2 9161/udp # NetLOCK2 -netlock2 9161/tcp # NetLOCK2 -netlock3 9162/udp # NetLOCK3 -netlock3 9162/tcp # NetLOCK3 -netlock4 9163/udp # NetLOCK4 -netlock4 9163/tcp # NetLOCK4 -netlock5 9164/udp # NetLOCK5 -netlock5 9164/tcp # NetLOCK5 -# Steven Sawkins -# 9165-9199 Unassigned -wap-wsp 9200/udp # WAP connectionless session service -wap-wsp 9200/tcp # WAP connectionless session service -wap-wsp-wtp 9201/udp # WAP session service -wap-wsp-wtp 9201/tcp # WAP session service -wap-wsp-s 9202/udp # WAP secure connectionless session service -wap-wsp-s 9202/tcp # WAP secure connectionless session service -wap-wsp-wtp-s 9203/udp # WAP secure session service -wap-wsp-wtp-s 9203/tcp # WAP secure session service -wap-vcard 9204/udp # WAP vCard -wap-vcard 9204/tcp # WAP vCard -wap-vcal 9205/udp # WAP vCal -wap-vcal 9205/tcp # WAP vCal -wap-vcard-s 9206/udp # WAP vCard Secure -wap-vcard-s 9206/tcp # WAP vCard Secure -wap-vcal-s 9207/udp # WAP vCal Secure -wap-vcal-s 9207/tcp # WAP vCal Secure -# WAP Forum -# WAP Forum -# 9208-9209 Unassigned -lif-mlp 9210/udp # LIF Mobile Locn Protocol -lif-mlp 9210/tcp # LIF Mobile Locn Protocol -lif-mlp-s 9211/udp # LIF Mobile Locn Secure -lif-mlp-s 9211/tcp # LIF Mobile Locn Secure -# Location Interoperability Forum -# April 2002 -# 9212-9216 Unassigned -fsc-port 9217/udp # FSC Communication Port -fsc-port 9217/tcp # FSC Communication Port -# Teijo Mustonen March 2002 -# 9218-9280 Unassigned -swtp-port1 9281/udp # SofaWare transport port 1 -swtp-port1 9281/tcp # SofaWare transport port 1 -swtp-port2 9282/udp # SofaWare transport port 2 -swtp-port2 9282/tcp # SofaWare transport port 2 -# Amir Rapson February 2002 -callwaveiam 9283/udp # CallWaveIAM -callwaveiam 9283/tcp # CallWaveIAM -# Colin Kelley -visd 9284/udp # VERITAS Information Serve -visd 9284/tcp # VERITAS Information Serve -# Ravi Tavakely February 2002 -n2h2server 9285/udp # N2H2 Filter Service Port -n2h2server 9285/tcp # N2H2 Filter Service Port -# Jim Irwin February 2002 -# 9286 Unassigned -cumulus 9287/udp # Cumulus -cumulus 9287/tcp # Cumulus -# Thomas Schleu -# 9288-9291 Unassigned -armtechdaemon 9292/udp # ArmTech Daemon -armtechdaemon 9292/tcp # ArmTech Daemon -# Rohan Story -# 9293-9320 Unassigned -guibase 9321/udp # guibase -guibase 9321/tcp # guibase -# Yutaka Ono -# 9322-9342 Unassigned -mpidcmgr 9343/udp # MpIdcMgr -mpidcmgr 9343/tcp # MpIdcMgr -mphlpdmc 9344/udp # Mphlpdmc -mphlpdmc 9344/tcp # Mphlpdmc -# Yutaka Ono -# 9345 Unassigned -ctechlicensing 9346/udp # C Tech Licensing -ctechlicensing 9346/tcp # C Tech Licensing -# Reed Copsey, Jr. -# 9347-9373 Unassigned -fjdmimgr 9374/udp # fjdmimgr -fjdmimgr 9374/tcp # fjdmimgr -# Yutaka Ono -# 9375-9395 Unassigned -fjinvmgr 9396/udp # fjinvmgr -fjinvmgr 9396/tcp # fjinvmgr -mpidcagt 9397/udp # MpIdcAgt -mpidcagt 9397/tcp # MpIdcAgt -# Yutaka Ono -# 9398-9499 Unassigned -ismserver 9500/udp # ismserver -ismserver 9500/tcp # ismserver -# Ian Gordon -# 9501-9534 Unassigned -mngsuite 9535/udp # Management Suite Remote Control -mngsuite 9535/tcp # Management Suite Remote Control -# Alan Butt -# 9536-9593 Unassigned -msgsys 9594/udp # Message System -msgsys 9594/tcp # Message System -pds 9595/udp # Ping Discovery Service -pds 9595/tcp # Ping Discovery Service -# Alan Butt -# 9596-9599 Unassigned -micromuse-ncpw 9600/udp # MICROMUSE-NCPW -micromuse-ncpw 9600/tcp # MICROMUSE-NCPW -# Hing Wing To -# 9601-9611 Unassigned -streamcomm-ds 9612/udp # StreamComm User Directory -streamcomm-ds 9612/tcp # StreamComm User Directory -# Brian C. Wiles -# 9613-9746 Unassigned -l5nas-parchan 9747/udp # L5NAS Parallel Channel -l5nas-parchan 9747/tcp # L5NAS Parallel Channel -# Lawrence J. Dickson - Land-5 Corporation -# March 2002 -# 9748-9752 Unassigned -rasadv 9753/udp # rasadv -rasadv 9753/tcp # rasadv -# Dave Thaler -# 9754-9799 Unassigned -davsrc 9800/udp # WebDav Source Port -davsrc 9800/tcp # WebDav Source Port -# Ethan Fremen -sstp-2 9801/udp # Sakura Script Transfer Protocol-2 -sstp-2 9801/tcp # Sakura Script Transfer Protocol-2 -# Kouichi Takeda -# 9802-9874 Unassigned -sapv1 9875/udp # Session Announcement v1 -sapv1 9875/tcp # Session Announcement v1 -# RFC 2974 -sd 9876/udp # Session Director -sd 9876/tcp # Session Director -# Van Jacobson -cyborg-systems 9888/udp # CYBORG Systems -cyborg-systems 9888/tcp # CYBORG Systems -# Malcolm Graham -monkeycom 9898/udp # MonkeyCom -monkeycom 9898/tcp # MonkeyCom -# Yuji Kuwabara -sctp-tunneling 9899/udp # SCTP TUNNELING -sctp-tunneling 9899/tcp # SCTP TUNNELING -iua 9900/sctp # IUA -iua 9900/udp # IUA -iua 9900/tcp # IUA -# Lyndon Ong -# 9901-9908 Unassigned -domaintime 9909/udp # domaintime -domaintime 9909/tcp # domaintime -# Jeffry Dwight -# 9910 Unassigned -sype-transport 9911/udp # SYPECom Transport Protocol -sype-transport 9911/tcp # SYPECom Transport Protocol -# Sylvain Pedneault March 2003 -# 9912-9949 Unassigned -apc-9950 9950/udp # APC 9950 -apc-9950 9950/tcp # APC 9950 -apc-9951 9951/udp # APC 9951 -apc-9951 9951/tcp # APC 9951 -apc-9952 9952/udp # APC 9952 -apc-9952 9952/tcp # APC 9952 -# American Power Conversion -# 9953-9991 Unassigned -palace-1 9992/udp # OnLive-1 -palace-1 9992/tcp # OnLive-1 -palace-2 9993/udp # OnLive-2 -palace-2 9993/tcp # OnLive-2 -palace-3 9994/udp # OnLive-3 -palace-3 9994/tcp # OnLive-3 -palace-4 9995/udp # Palace-4 -palace-4 9995/tcp # Palace-4 -palace-5 9996/udp # Palace-5 -palace-5 9996/tcp # Palace-5 -palace-6 9997/udp # Palace-6 -palace-6 9997/tcp # Palace-6 -# Douglas Crockford -distinct32 9998/udp # Distinct32 -distinct32 9998/tcp # Distinct32 -distinct 9999/udp # distinct -distinct 9999/tcp # distinct -# Anoop Tewari -ndmp 10000/udp # Network Data Management Protocol -ndmp 10000/tcp # Network Data Management Protocol -# Brian Ehrmantraut -scp-config 10001/udp # SCP Configuration Port -scp-config 10001/tcp # SCP Configuration Port -# Brad Strand -# 10002-10006 Unassigned -mvs-capacity 10007/udp # MVS Capacity -mvs-capacity 10007/tcp # MVS Capacity -# Donna Dillenberger -octopus 10008/udp # Octopus Multiplexer -octopus 10008/tcp # Octopus Multiplexer -# Chris Koeritz October 2002 -# 10009-10079 Unassigned -amanda 10080/udp # Amanda -amanda 10080/tcp # Amanda -# John Jackson -# -# 10081-10100 Unassigned -ezmeeting-2 10101/udp # eZmeeting -ezmeeting-2 10101/tcp # eZmeeting -ezproxy-2 10102/udp # eZproxy -ezproxy-2 10102/tcp # eZproxy -ezrelay 10103/udp # eZrelay -ezrelay 10103/tcp # eZrelay -# Albert C. Yang March 2002 -# 10104-10112 Unassigned -netiq-endpoint 10113/udp # NetIQ Endpoint -netiq-endpoint 10113/tcp # NetIQ Endpoint -netiq-qcheck 10114/udp # NetIQ Qcheck -netiq-qcheck 10114/tcp # NetIQ Qcheck -# John Wood -netiq-endpt 10115/udp # NetIQ Endpoint -netiq-endpt 10115/tcp # NetIQ Endpoint -# Gary Weichinger -netiq-voipa 10116/udp # NetIQ VoIP Assessor -netiq-voipa 10116/tcp # NetIQ VoIP Assessor -# Gary Weichinger -# 10117-10127 Unassigned -bmc-perf-sd 10128/udp # BMC-PERFORM-SERVICE DAEMON -bmc-perf-sd 10128/tcp # BMC-PERFORM-SERVICE DAEMON -# Dima Seliverstov -# 10129-10259 Unassigned -axis-wimp-port 10260/udp # Axis WIMP Port -axis-wimp-port 10260/tcp # Axis WIMP Port -# Stefan Eriksson -# 10261-10287 Unassigned -blocks 10288/udp # Blocks -blocks 10288/tcp # Blocks -# Carl Malamud -# 10289-10989 Unassigned -rmiaux 10990/udp # Auxiliary RMI Port -rmiaux 10990/tcp # Auxiliary RMI Port -# Eugen Bacic -# 10991-10999 Unassigned -irisa 11000/udp # IRISA -irisa 11000/tcp # IRISA -# Vladimir Brauner -metasys 11001/udp # Metasys -metasys 11001/tcp # Metasys -# Tobin Schuster -# 11002-11110 Unassigned -vce 11111/udp # Viral Computing Environment (VCE) -vce 11111/tcp # Viral Computing Environment (VCE) -# Fred Cohen -# 11112-11200 Unassigned -smsqp 11201/udp # smsqp -smsqp 11201/tcp # smsqp -# Andres Seco Hernandez -# 11202-11318 Unassigned -imip 11319/udp # IMIP -imip 11319/tcp # IMIP -# IM Unified Coalition, Len Zuvela -# -imip-channels 11320/udp # IMIP Channels Port -imip-channels 11320/tcp # IMIP Channels Port -# Len Zuvela -arena-server 11321/udp # Arena Server Listen -arena-server 11321/tcp # Arena Server Listen -# Earl Brannigan -# 11322-11366 Unassigned -atm-uhas 11367/udp # ATM UHAS -atm-uhas 11367/tcp # ATM UHAS -# Todd Barker -# 11368-11370 Unassigned -hkp 11371/udp # OpenPGP HTTP Keyserver -hkp 11371/tcp # OpenPGP HTTP Keyserver -# David Shaw May 2003 -# 11372-11599 Unassigned -tempest-port 11600/udp # Tempest Protocol Port -tempest-port 11600/tcp # Tempest Protocol Port -# Francis Cianfrocca -# 11601-11719 Unassigned -h323callsigalt 11720/udp # h323 Call Signal Alternate -h323callsigalt 11720/tcp # h323 Call Signal Alternate -# Chris White -# 11721-11750 Unassigned -intrepid-ssl 11751/udp # Intrepid SSL -intrepid-ssl 11751/tcp # Intrepid SSL -# Robert Eden March 2003 -# 11752-11966 Unassigned -sysinfo-sp 11967/udp # SysInfo Sercice Protocol -sysinfo-sp 11967/tcp # SysInfo Service Protocol -# Mike Cooper March 2003 -# 11968-11999 Unassiged -entextxid 12000/udp # IBM Enterprise Extender SNA XID Exchange -entextxid 12000/tcp # IBM Enterprise Extender SNA XID Exchange -entextnetwk 12001/udp # IBM Enterprise Extender SNA COS Network Priority -entextnetwk 12001/tcp # IBM Enterprise Extender SNA COS Network Priority -entexthigh 12002/udp # IBM Enterprise Extender SNA COS High Priority -entexthigh 12002/tcp # IBM Enterprise Extender SNA COS High Priority -entextmed 12003/udp # IBM Enterprise Extender SNA COS Medium Priority -entextmed 12003/tcp # IBM Enterprise Extender SNA COS Medium Priority -entextlow 12004/udp # IBM Enterprise Extender SNA COS Low Priority -entextlow 12004/tcp # IBM Enterprise Extender SNA COS Low Priority -# Eugene Cox -dbisamserver1 12005/udp # DBISAM Database Server - Regular -dbisamserver1 12005/tcp # DBISAM Database Server - Regular -dbisamserver2 12006/udp # DBISAM Database Server - Admin -dbisamserver2 12006/tcp # DBISAM Database Server - Admin -# Tim Young May 2002 -# 12007-12108 Unassigned -rets-ssl 12109/udp # RETS over SSL -rets-ssl 12109/tcp # RETS over SSL -# Bruce Toback February 2003 -# 12110-12171 Unassigned -hivep 12172/udp # HiveP -hivep 12172/tcp # HiveP -# Dick Augustsson -# 12173-12344 Unassigned -italk 12345/udp # Italk Chat System -italk 12345/tcp # Italk Chat System -# Takayuki Ito -# 12346-12752 Unassigned -tsaf 12753/udp # tsaf port -tsaf 12753/tcp # tsaf port -# Andreas Fehr <100042.2070@CompuServe.COM> -# 12754-13159 Unassigned -i-zipqd 13160/udp # I-ZIPQD -i-zipqd 13160/tcp # I-ZIPQD -# Chuck Runquist -# 13161-13222 Unassigned -powwow-client 13223/udp # PowWow Client -powwow-client 13223/tcp # PowWow Client -powwow-server 13224/udp # PowWow Server -powwow-server 13224/tcp # PowWow Server -# Paul K. Peterson -# 13225-13719 Unassigned -bprd 13720/udp # BPRD Protocol (VERITAS NetBackup) -bprd 13720/tcp # BPRD Protocol (VERITAS NetBackup) -bpdbm 13721/udp # BPDBM Protocol (VERITAS NetBackup) -bpdbm 13721/tcp # BPDBM Protocol (VERITAS NetBackup) -# Jeff Holmbeck -bpjava-msvc 13722/udp # BP Java MSVC Protocol -bpjava-msvc 13722/tcp # BP Java MSVC Protocol -# Tim Schmidt -# 13723 Unassigned -vnetd 13724/udp # Veritas Network Utility -vnetd 13724/tcp # Veritas Network Utility -# Jeff Holmbeck -# 13725-13781 Unassigned -bpcd 13782/udp # VERITAS NetBackup -bpcd 13782/tcp # VERITAS NetBackup -vopied 13783/udp # VOPIED Protocol -vopied 13783/tcp # VOPIED Protocol -# Jeff Holmbeck -# 13784-13817 Unassigned -dsmcc-config 13818/udp # DSMCC Config -dsmcc-config 13818/tcp # DSMCC Config -dsmcc-session 13819/udp # DSMCC Session Messages -dsmcc-session 13819/tcp # DSMCC Session Messages -dsmcc-passthru 13820/udp # DSMCC Pass-Thru Messages -dsmcc-passthru 13820/tcp # DSMCC Pass-Thru Messages -dsmcc-download 13821/udp # DSMCC Download Protocol -dsmcc-download 13821/tcp # DSMCC Download Protocol -dsmcc-ccp 13822/udp # DSMCC Channel Change Protocol -dsmcc-ccp 13822/tcp # DSMCC Channel Change Protocol -# Tim Addington -# ISO/IEC 13818-6 MPEG-2 DSM-CC -# 13823-14000 Unassigned -sua 14001/sctp # SUA -sua 14001/udp # De-Registered (2001 June 06) -sua 14001/tcp # SUA -# Miguel Angel Garcia -# 14002-14032 Unassigned -sage-best-com1 14033/udp # sage Best! Config Server 1 -sage-best-com1 14033/tcp # sage Best! Config Server 1 -sage-best-com2 14034/udp # sage Best! Config Server 2 -sage-best-com2 14034/tcp # sage Best! Config Server 2 -# Christian Rubach -# 14035-14140 Unassigned -vcs-app 14141/udp # VCS Application -vcs-app 14141/tcp # VCS Application -# Ming Xu -# 14142-14144 Unassigned -gcm-app 14145/udp # GCM Application -gcm-app 14145/tcp # GCM Application -# Ming Xu -# 14146-14148 Unassigned -vrts-tdd 14149/udp # Veritas Traffic Director -vrts-tdd 14149/tcp # Veritas Traffic Director -# Sameer Deokule March 2002 -# 14150-14935 Unassigned -hde-lcesrvr-1 14936/udp # hde-lcesrvr-1 -hde-lcesrvr-1 14936/tcp # hde-lcesrvr-1 -hde-lcesrvr-2 14937/udp # hde-lcesrvr-2 -hde-lcesrvr-2 14937/tcp # hde-lcesrvr-2 -# Horizon Digital Enterprise, Inc. -# 14938-14999 Unassigned -hydap 15000/udp # Hypack Data Aquisition -hydap 15000/tcp # Hypack Data Aquisition -# Mircea Neacsu -# 15001-15344 Unassigned -xpilot 15345/udp # XPilot Contact Port -xpilot 15345/tcp # XPilot Contact Port -# Bert Gijsbers -# 15346-15362 Unassigned -3link 15363/udp # 3Link Negotiation -3link 15363/tcp # 3Link Negotiation -# Brant Thomsen January 2003 -# 15364-16359 Unassigned -netserialext1 16360/udp # netserialext1 -netserialext1 16360/tcp # netserialext1 -netserialext2 16361/udp # netserialext2 -netserialext2 16361/tcp # netserialext2 -# Mike Hoy -# 16362-16366 Unassigned -netserialext3 16367/udp # netserialext3 -netserialext3 16367/tcp # netserialext3 -netserialext4 16368/udp # netserialext4 -netserialext4 16368/tcp # netserialext4 -# Mike Hoy -# 16369-16990 Unassigned -intel-rci-mp 16991/udp # INTEL-RCI-MP -intel-rci-mp 16991/tcp # INTEL-RCI-MP -# Jane Dashevsky -# 16992-17006 Unassigned -isode-dua 17007/udp # -isode-dua 17007/tcp # -# 17008-17184 Unassigned -soundsvirtual 17185/udp # Sounds Virtual -soundsvirtual 17185/tcp # Sounds Virtual -# Richard Snider -# 17186-17218 Unassigned -chipper 17219/udp # Chipper -chipper 17219/tcp # Chipper -# Ronald Jimmink -# 17220-17999 Unassigned -biimenu 18000/udp # Beckman Instruments, Inc. -biimenu 18000/tcp # Beckman Instruments, Inc. -# R. L. Meyering -# 18001-18180 Unassigned -opsec-cvp 18181/udp # OPSEC CVP -opsec-cvp 18181/tcp # OPSEC CVP -opsec-ufp 18182/udp # OPSEC UFP -opsec-ufp 18182/tcp # OPSEC UFP -# Alon Kantor -opsec-sam 18183/udp # OPSEC SAM -opsec-sam 18183/tcp # OPSEC SAM -opsec-lea 18184/udp # OPSEC LEA -opsec-lea 18184/tcp # OPSEC LEA -opsec-omi 18185/udp # OPSEC OMI -opsec-omi 18185/tcp # OPSEC OMI -# Alon Kantor -# 18186 Unassigned -opsec-ela 18187/udp # OPSEC ELA -opsec-ela 18187/tcp # OPSEC ELA -# Alon Kantor -# 18188-18240 Unassigned -checkpoint-rtm 18241/udp # Check Point RTM -checkpoint-rtm 18241/tcp # Check Point RTM -# Dudi Hazan -# 18242-18462 Unassigned -ac-cluster 18463/udp # AC Cluster -ac-cluster 18463/tcp # AC Cluster -# Lisa Zhong -# 18464-18768 Unassigned -ique 18769/udp # IQue Protocol -ique 18769/tcp # IQue Protocol -# Avi Drissman July 2002 -# 18770-18887 Unassigned -apc-necmp 18888/udp # APCNECMP -apc-necmp 18888/tcp # APCNECMP -# Michael Yip -# 18889-19190 Unassigned -opsec-uaa 19191/udp # OPSEC UAA -opsec-uaa 19191/tcp # OPSEC UAA -# Reuven Harrison -# 19192-19193 Unassigned -ua-secureagent 19194/udp # UserAuthority SecureAgent -ua-secureagent 19194/tcp # UserAuthority SecureAgent -# Reuven Harrison January 2003 -# 19195-19282 Unassigned -keysrvr 19283/udp # Key Server for SASSAFRAS -keysrvr 19283/tcp # Key Server for SASSAFRAS -# Mark Valence -# 19284-19314 Unassigned -keyshadow 19315/udp # Key Shadow for SASSAFRAS -keyshadow 19315/tcp # Key Shadow for SASSAFRAS -# Mark Valence -# 19316-19397 Unassigned -mtrgtrans 19398/udp # mtrgtrans -mtrgtrans 19398/tcp # mtrgtrans -# Katsuhito Muroi -# 19399-19409 Unassigned -hp-sco 19410/udp # hp-sco -hp-sco 19410/tcp # hp-sco -hp-sca 19411/udp # hp-sca -hp-sca 19411/tcp # hp-sca -# Larry Schwartz -hp-sessmon 19412/udp # HP-SESSMON -hp-sessmon 19412/tcp # HP-SESSMON -# Gita Murthy -# 19413-19539 Unassigned -sxuptp 19540/udp # SXUPTP -sxuptp 19540/tcp # SXUPTP -# Keiji Okuma August 2002 -jcp 19541/udp # JCP Client -jcp 19541/tcp # JCP Client -# Yuji Sasaki -# 19542-19999 Unassigned -dnp 20000/udp # DNP -dnp 20000/tcp # DNP -# Michael Thesing -# 20001-20201 Unassigned -ipdtp-port 20202/udp # IPD Tunneling Port -ipdtp-port 20202/tcp # IPD Tunneling Port -# Vikki Yin Wei January 2003 -# 20203-20221 Unassigned -ipulse-ics 20222/udp # iPulse-ICS -ipulse-ics 20222/tcp # iPulse-ICS -# Meggie Garica-Woodruff -# 20223-20669 Unassigned -track 20670/udp # Track -track 20670/tcp # Track -# Michael Sweet -# 20671-20998 Unassigned -athand-mmp 20999/udp # AT Hand MMP -athand-mmp 20999/tcp # At Hand MMP -# Stepan Riha -# 20300-21589 Unassigned -vofr-gateway 21590/udp # VoFR Gateway -vofr-gateway 21590/tcp # VoFR Gateway -# Marty Borden -# 21591-21799 Unassigned -tvpm 21800/udp # TVNC Pro Multiplexing -tvpm 21800/tcp # TVNC Pro Multiplexing -# Brian Blevins -# 21801-21844 Unassigned -webphone 21845/udp # webphone -webphone 21845/tcp # webphone -netspeak-is 21846/udp # NetSpeak Corp. Directory Services -netspeak-is 21846/tcp # NetSpeak Corp. Directory Services -netspeak-cs 21847/udp # NetSpeak Corp. Connection Services -netspeak-cs 21847/tcp # NetSpeak Corp. Connection Services -netspeak-acd 21848/udp # NetSpeak Corp. Automatic Call Distribution -netspeak-acd 21848/tcp # NetSpeak Corp. Automatic Call Distribution -netspeak-cps 21849/udp # NetSpeak Corp. Credit Processing System -netspeak-cps 21849/tcp # NetSpeak Corp. Credit Processing System -# Toby Hosterman -# 21850-21999 Unassigned -snapenetio 22000/udp # SNAPenetIO -snapenetio 22000/tcp # SNAPenetIO -optocontrol 22001/udp # OptoControl -optocontrol 22001/tcp # OptoControl -# Kevin Kuhns -# 22002-22272 Unassigned -wnn6 22273/udp # wnn6 -wnn6 22273/tcp # wnn6 -# Yasunari Gon Yamasita Scott_Petrack@vocaltec.com> -# 22556-22799 Unassigned -aws-brf 22800/udp # Telerate Information Platform LAN -aws-brf 22800/tcp # Telerate Information Platform LAN -# Timo Sivonen -# 22801-22950 Unassigned -brf-gw 22951/udp # Telerate Information Platform WAN -brf-gw 22951/tcp # Telerate Information Platform WAN -# Timo Sivonen -# 22952-23999 Unassigned -med-ltp 24000/udp # med-ltp -med-ltp 24000/tcp # med-ltp -med-fsp-rx 24001/udp # med-fsp-rx -med-fsp-rx 24001/tcp # med-fsp-rx -med-fsp-tx 24002/udp # med-fsp-tx -med-fsp-tx 24002/tcp # med-fsp-tx -med-supp 24003/udp # med-supp -med-supp 24003/tcp # med-supp -med-ovw 24004/udp # med-ovw -med-ovw 24004/tcp # med-ovw -med-ci 24005/udp # med-ci -med-ci 24005/tcp # med-ci -med-net-svc 24006/udp # med-net-svc -med-net-svc 24006/tcp # med-net-svc -# Juergen Fischbach -# 24007-24241 Unassigned -filesphere 24242/udp # fileSphere -filesphere 24242/tcp # fileSphere -# Carl Cedergren -# 24243-24248 Unassigned -vista-4gl 24249/udp # Vista 4GL -vista-4gl 24249/tcp # Vista 4GL -# Mark Itzcovitz -# 24250-24385 Unassigned -intel_rci 24386/udp # Intel RCI -intel_rci 24386/tcp # Intel RCI -# Mark Lewis -# 24387-24553 Unassigned -binkp 24554/udp # BINKP -binkp 24554/tcp # BINKP -# Max Masyutin -# 24554-34676 Unassigned -flashfiler 24677/udp # FlashFiler -flashfiler 24677/tcp # FlashFiler -# Ben Oram -proactivate 24678/udp # Turbopower Proactivate -proactivate 24678/tcp # Turbopower Proactivate -# Ben Oram -# 24679-24921 Unassigned -snip 24922/udp # Simple Net Ident Protocol -snip 24922/tcp # Simple Net Ident Protocol -# Jean-Paul Moreaux -# -# 24923-24999 Unassigned -icl-twobase1 25000/udp # icl-twobase1 -icl-twobase1 25000/tcp # icl-twobase1 -icl-twobase2 25001/udp # icl-twobase2 -icl-twobase2 25001/tcp # icl-twobase2 -icl-twobase3 25002/udp # icl-twobase3 -icl-twobase3 25002/tcp # icl-twobase3 -icl-twobase4 25003/udp # icl-twobase4 -icl-twobase4 25003/tcp # icl-twobase4 -icl-twobase5 25004/udp # icl-twobase5 -icl-twobase5 25004/tcp # icl-twobase5 -icl-twobase6 25005/udp # icl-twobase6 -icl-twobase6 25005/tcp # icl-twobase6 -icl-twobase7 25006/udp # icl-twobase7 -icl-twobase7 25006/tcp # icl-twobase7 -icl-twobase8 25007/udp # icl-twobase8 -icl-twobase8 25007/tcp # icl-twobase8 -icl-twobase9 25008/udp # icl-twobase9 -icl-twobase9 25008/tcp # icl-twobase9 -icl-twobase10 25009/udp # icl-twobase10 -icl-twobase10 25009/tcp # icl-twobase10 -# J. A. (Tony) Sever -# 25010-25792 Unassigned -vocaltec-hos 25793/udp # Vocaltec Address Server -vocaltec-hos 25793/tcp # Vocaltec Address Server -# Scott Petrack -# 25794-25900 Unassigned -niobserver 25901/udp # NIObserver -niobserver 25901/tcp # NIObserver -# Roman Oliynyk -# 25902 Unassigned -niprobe 25903/udp # NIProbe -niprobe 25903/tcp # NIProbe -# Roman Oliynyk -# 25904-25999 Unassigned -quake 26000/udp # quake -quake 26000/tcp # quake -# Yasunari Gon Yamasita -# 26001-26207 Unassigned -wnn6-ds 26208/udp # wnn6-ds -wnn6-ds 26208/tcp # wnn6-ds -# Yasunari Gon Yamasita -# 26209-26259 Unassigned -ezproxy 26260/udp # eZproxy -ezproxy 26260/tcp # eZproxy -ezmeeting 26261/udp # eZmeeting -ezmeeting 26261/tcp # eZmeeting -# Albert C. Yang -k3software-svr 26262/udp # K3 Software-Server -k3software-svr 26262/tcp # K3 Software-Server -k3software-cli 26263/udp # K3 Software-Client -k3software-cli 26263/tcp # K3 Software-Client -# Jim Baldridge -gserver 26264/udp # Gserver -gserver 26264/tcp # Gserver -# Szanto Gabor -# 26265-26999 Unassigned -# Daniel Birns -# 27010-27344 Unassigned -imagepump 27345/udp # ImagePump -imagepump 27345/tcp # ImagePump -# Richard Minner -# 27346-27503 Unassigned -kopek-httphead 27504/udp # Kopek HTTP Head Port -kopek-httphead 27504/tcp # Kopek HTTP Head Port -# Sten H. Danielsen July 2002 -# 27505-27998 Unassigned -tw-auth-key 27999/udp # Attribute Certificate Services -tw-auth-key 27999/tcp # TW Authentication/Key Distribution and -# Alex Duncan -# 28000-30000 Unassigned -pago-services1 30001/udp # Pago Services 1 -pago-services1 30001/tcp # Pago Services 1 -pago-services2 30002/udp # Pago Services 2 -pago-services2 30002/tcp # Pago Services 2 -# Balduin Mueller-Platz -# March 2002 -# 30003-31415 Unassigned -xqosd 31416/udp # XQoS network monitor -xqosd 31416/tcp # XQoS network monitor -# Joe Elliott June 2002 -# 31417-31619 Unassigned -lm-mon 31620/udp # lm mon -lm-mon 31620/tcp # lm mon -# Mounir Hahad June 2003 -# 31621-31764 Unassigned -gamesmith-port 31765/udp # GameSmith Port -gamesmith-port 31765/tcp # GameSmith Port -# Randy Thompson August 2002 -# 31766-32767 Unassigned -filenet-tms 32768/udp # Filenet TMS -filenet-tms 32768/tcp # Filenet TMS -filenet-rpc 32769/udp # Filenet RPC -filenet-rpc 32769/tcp # Filenet RPC -filenet-nch 32770/udp # Filenet NCH -filenet-nch 32770/tcp # Filenet NCH -# Daniel Whelan -filenet-rmi 32771/udp # FileNet RMI -filenet-rmi 32771/tcp # FileNET RMI -# Chris Adkins -filenet-pa 32772/udp # FileNET Process Analyzer -filenet-pa 32772/tcp # FileNET Process Analyzer -# Chris Adkins January 2003 -# 32773-32895 Unassigned -idmgratm 32896/udp # Attachmate ID Manager -idmgratm 32896/tcp # Attachmate ID Manager -# George Gianelos March 2003 -# 32897-33330 Unassigned -diamondport 33331/udp # DiamondCentral Interface -diamondport 33331/tcp # DiamondCentral Interface -# Edward Browdy July 2002 -# 33332-33433 Unassigned -traceroute 33434/udp # traceroute use -traceroute 33434/tcp # traceroute use -# IANA -# 33435-34248 Unassigned -turbonote-2 34249/udp # TurboNote Relay Server Default Port -turbonote-2 34249/tcp # TurboNote Relay Server Default Port -# Peter Hyde -# 34250-36864 Unassigned -kastenxpipe 36865/udp # KastenX Pipe -kastenxpipe 36865/tcp # KastenX Pipe -# Guy Cheng -# 36866-37474 Unassigned -neckar 37475/udp # science + computing's Venus Administration Port -neckar 37475/tcp # science + computing's Venus Administration Port -# Ralf Allrutz February 2002 -# 37476-38200 Unassigned -galaxy7-data 38201/udp # Galaxy7 Data Tunnel -galaxy7-data 38201/tcp # Galaxy7 Data Tunnel -# Tatham Oddie September 2002 -# 38202-39680 Unassigned -turbonote-1 39681/udp # TurboNote Default Port -turbonote-1 39681/tcp # TurboNote Default Port -# Peter Hyde -# 39682-40840 Unassigned -cscp 40841/udp # CSCP -cscp 40841/tcp # CSCP -# Michael Dodge -csccredir 40842/udp # CSCCREDIR -csccredir 40842/tcp # CSCCREDIR -csccfirewall 40843/udp # CSCCFIREWALL -csccfirewall 40843/tcp # CSCCFIREWALL -# Sudhir Menon -# 40844-41110 Unassigned -fs-qos 41111/udp # Foursticks QoS Protocol -fs-qos 41111/tcp # Foursticks QoS Protocol -# Chee Kent Lam April 2002 -# 41112-41793 Unassigned -crestron-cip 41794/udp # Crestron Control Port -crestron-cip 41794/tcp # Crestron Control Port -crestron-ctp 41795/udp # Crestron Terminal Port -crestron-ctp 41795/tcp # Crestron Terminal Port -# Ed Ranney January 2003 -# 41796-43187 Unassigned -reachout 43188/udp # REACHOUT -reachout 43188/tcp # REACHOUT -ndm-agent-port 43189/udp # NDM-AGENT-PORT -ndm-agent-port 43189/tcp # NDM-AGENT-PORT -ip-provision 43190/udp # IP-PROVISION -ip-provision 43190/tcp # IP-PROVISION -# Roman Kriis -# 43191-44320 Unassigned -pmcd 44321/udp # PCP server (pmcd) -pmcd 44321/tcp # PCP server (pmcd) -# Ken McDonell June 2002 -# 44322-44817 Unassigned -rockwell-encap 44818/udp # Rockwell Encapsulation -rockwell-encap 44818/tcp # Rockwell Encapsulation -# Brian Batke -# 44819-45053 Unassigned -invision-ag 45054/udp # InVision AG -invision-ag 45054/tcp # InVision AG -# Matthias Schroer -# 45055-45677 Unassigned -eba 45678/udp # EBA PRISE -eba 45678/tcp # EBA PRISE -# Patrick Kara -# 45679-45965 Unassigned -ssr-servermgr 45966/udp # SSRServerMgr -ssr-servermgr 45966/tcp # SSRServerMgr -# Jeremy Gilliat -# 45967-46999 Unassigned -mbus 47000/udp # Message Bus -mbus 47000/tcp # Message Bus -# Dirk Kutscher -# 47001-47556 Unassigned -dbbrowse 47557/udp # Databeam Corporation -dbbrowse 47557/tcp # Databeam Corporation -# Cindy Martin -# 47558-47623 Unassigned -directplaysrvr 47624/udp # Direct Play Server -directplaysrvr 47624/tcp # Direct Play Server -# Ajay Jindal -# 47625-47805 Unassigned -ap 47806/udp # ALC Protocol -ap 47806/tcp # ALC Protocol -# Andrew Newton -# 47807 Unassigned -bacnet 47808/udp # Building Automation and Control Networks -bacnet 47808/tcp # Building Automation and Control Networks -# H. Michael Newman -# 47809-47999 Unassigned -nimcontroller 48000/udp # Nimbus Controller -nimcontroller 48000/tcp # Nimbus Controller -nimspooler 48001/udp # Nimbus Spooler -nimspooler 48001/tcp # Nimbus Spooler -nimhub 48002/udp # Nimbus Hub -nimhub 48002/tcp # Nimbus Hub -nimgtw 48003/udp # Nimbus Gateway -nimgtw 48003/tcp # Nimbus Gateway -# Carstein Seeberg -# 48004-48555 Unassigned -com-bardac-dw 48556/udp # com-bardac-dw -com-bardac-dw 48556/tcp # com-bardac-dw -# Nicholas J Howes -# 48557-49150 Unassigned -# 49151 IANA Reserved diff --git a/test/data/types/ssh_authorized_key/1 b/test/data/types/ssh_authorized_key/1 deleted file mode 100644 index 69d1af15e..000000000 --- a/test/data/types/ssh_authorized_key/1 +++ /dev/null @@ -1,2 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= francois.deppierraz@camptocamp.com -from="192.168.1.2",command="/usr/local/bin/backup.sh",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVesG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4ksG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4ksG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4kxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaL Backup system diff --git a/test/language/ast.rb b/test/language/ast.rb deleted file mode 100755 index ec20cdb99..000000000 --- a/test/language/ast.rb +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'puppet/parser/parser' -require 'puppettest/resourcetesting' -require 'puppettest/parsertesting' - -class TestAST < Test::Unit::TestCase - include PuppetTest::ParserTesting - include PuppetTest::ResourceTesting - - def test_if - scope = mkscope - astif = nil - astelse = nil - fakeelse = FakeAST.new(:else) - faketest = FakeAST.new(true) - fakeif = FakeAST.new(:if) - - assert_nothing_raised { - astelse = AST::Else.new(:statements => fakeelse) - } - assert_nothing_raised { - - astif = AST::IfStatement.new( - - :test => faketest, - :statements => fakeif, - - :else => astelse - ) - } - - # We initialized it to true, so we should get that first - ret = nil - assert_nothing_raised { - ret = astif.evaluate(scope) - } - assert_equal(:if, ret) - - # Now set it to false and check that - faketest.evaluate = false - assert_nothing_raised { - ret = astif.evaluate(scope) - } - assert_equal(:else, ret) - end - - # Make sure our override object behaves "correctly" - def test_override - scope = mkscope - - ref = nil - assert_nothing_raised do - ref = resourceoverride("file", "/yayness", "owner" => "blah", "group" => "boo") - end - - scope.compiler.expects(:add_override).with { |res| res.is_a?(Puppet::Parser::Resource) } - ret = nil - assert_nothing_raised do - ret = ref.evaluate scope - end - - assert_instance_of(Puppet::Parser::Resource, ret, "Did not return override") - end - - def test_collection - scope = mkscope - - coll = nil - assert_nothing_raised do - coll = AST::Collection.new(:type => "file", :form => :virtual) - end - - assert_instance_of(AST::Collection, coll) - - ret = nil - assert_nothing_raised do - ret = coll.evaluate scope - end - - assert_instance_of(Puppet::Parser::Collector, ret) - - # Now make sure we get it back from the scope - colls = scope.compiler.instance_variable_get("@collections") - assert_equal([ret], colls, "Did not store collector in config's collection list") - end -end diff --git a/test/language/functions.rb b/test/language/functions.rb deleted file mode 100755 index 2810b123a..000000000 --- a/test/language/functions.rb +++ /dev/null @@ -1,540 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/parser/parser' -require 'puppettest' -require 'puppettest/resourcetesting' - -class TestLangFunctions < Test::Unit::TestCase - include PuppetTest::ParserTesting - include PuppetTest::ResourceTesting - def test_functions - Puppet::Node::Environment.stubs(:current).returns nil - assert_nothing_raised do - - Puppet::Parser::AST::Function.new( - - :name => "fakefunction", - - :arguments => AST::ASTArray.new( - :children => [nameobj("avalue")] - ) - ) - end - - assert_raise(Puppet::ParseError) do - - func = Puppet::Parser::AST::Function.new( - - :name => "fakefunction", - - :arguments => AST::ASTArray.new( - :children => [nameobj("avalue")] - ) - ) - func.evaluate(mkscope) - end - - assert_nothing_raised do - Puppet::Parser::Functions.newfunction(:fakefunction, :type => :rvalue) do |input| - return "output #{input[0]}" - end - end - - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "fakefunction", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [nameobj("avalue")] - ) - ) - end - - scope = mkscope - val = nil - assert_nothing_raised do - val = func.evaluate(scope) - end - - assert_equal("output avalue", val) - end - - def test_taggedfunction - scope = mkscope - scope.resource.tag("yayness") - - # Make sure the ast stuff does what it's supposed to - {"yayness" => true, "booness" => false}.each do |tag, retval| - func = taggedobj(tag, :rvalue) - - val = nil - assert_nothing_raised do - val = func.evaluate(scope) - end - - assert_equal(retval, val, "'tagged' returned #{val} for #{tag}") - end - - # Now make sure we correctly get tags. - scope.resource.tag("resourcetag") - assert(scope.function_tagged("resourcetag"), "tagged function did not catch resource tags") - scope.compiler.catalog.tag("configtag") - assert(scope.function_tagged("configtag"), "tagged function did not catch catalog tags") - end - - def test_failfunction - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "fail", - :ftype => :statement, - - :arguments => AST::ASTArray.new( - :children => [stringobj("this is a failure"), stringobj("and another")] - ) - ) - end - - scope = mkscope - val = nil - assert_raise(Puppet::ParseError) do - val = func.evaluate(scope) - end - end - - def test_multipletemplates - Dir.mkdir(Puppet[:templatedir]) - onep = File.join(Puppet[:templatedir], "one") - twop = File.join(Puppet[:templatedir], "two") - - File.open(onep, "w") do |f| - f.puts "<%- if @one.nil? then raise '@one undefined' end -%>template <%= @one %>" - end - - File.open(twop, "w") do |f| - f.puts "template <%= @two %>" - end - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "template", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [stringobj("one"), stringobj("two")] - ) - ) - end - ast = varobj("output", func) - - scope = mkscope - - # Test that our manual exception throw fails the parse - assert_raise(Puppet::ParseError) do - ast.evaluate(scope) - end - - # Test that our use of an undefined instance variable does not throw - # an exception, but only safely continues. - scope['one'] = "One" - assert_nothing_raised do - ast.evaluate(scope) - end - - # Ensure that we got the output we expected from that evaluation. - assert_equal("template One\ntemplate \n", scope['output'], "Undefined template variables do not raise exceptions") - - # Now, fill in the last variable and make sure the whole thing - # evaluates correctly. - scope['two'] = "Two" - scope.unsetvar("output") - assert_nothing_raised do - ast.evaluate(scope) - end - - - assert_equal( - "template One\ntemplate Two\n", scope['output'], - - "Templates were not handled correctly") - end - - # Now make sure we can fully qualify files, and specify just one - def test_singletemplates - template = tempfile - - File.open(template, "w") do |f| - f.puts "template <%= @yay.nil?() ? raise('yay undefined') : @yay %>" - end - - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "template", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [stringobj(template)] - ) - ) - end - ast = varobj("output", func) - - scope = mkscope - assert_raise(Puppet::ParseError) do - ast.evaluate(scope) - end - - scope['yay'] = "this is yay" - - assert_nothing_raised do - ast.evaluate(scope) - end - - - assert_equal( - "template this is yay\n", scope['output'], - - "Templates were not handled correctly") - - end - - # Make sure that legacy template variable access works as expected. - def test_legacyvariables - template = tempfile - - File.open(template, "w") do |f| - f.puts "template <%= deprecated %>" - end - - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "template", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [stringobj(template)] - ) - ) - end - ast = varobj("output", func) - - # Verify that we get an exception using old-style accessors. - scope = mkscope - assert_raise(Puppet::ParseError) do - ast.evaluate(scope) - end - - # Verify that we evaluate and return their value correctly. - scope["deprecated"] = "deprecated value" - assert_nothing_raised do - ast.evaluate(scope) - end - - - assert_equal( - "template deprecated value\n", scope['output'], - - "Deprecated template variables were not handled correctly") - end - - # Make sure that problems with kernel method visibility still exist. - def test_kernel_module_shadows_deprecated_var_lookup - template = tempfile - File.open(template, "w").puts("<%= binding %>") - - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "template", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [stringobj(template)] - ) - ) - end - ast = varobj("output", func) - - # Verify that Kernel methods still shadow deprecated variable lookups. - scope = mkscope - assert_nothing_raised("No exception for Kernel shadowed variable names") do - ast.evaluate(scope) - end - end - - def test_tempatefunction_cannot_see_scopes - template = tempfile - - File.open(template, "w") do |f| - f.puts "<%= lookupvar('myvar') %>" - end - - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "template", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [stringobj(template)] - ) - ) - end - ast = varobj("output", func) - - scope = mkscope - scope['myvar'] = "this is yayness" - assert_raise(Puppet::ParseError) do - ast.evaluate(scope) - end - end - - def test_template_reparses - template = tempfile - - File.open(template, "w") do |f| - f.puts "original text" - end - - file = tempfile - - Puppet[:code] = %{file { "#{file}": content => template("#{template}") }} - Puppet[:environment] = "yay" - node = mknode - node.stubs(:environment).returns Puppet::Node::Environment.new - - Puppet[:environment] = "yay" - - catalog = Puppet::Parser::Compiler.new(node).compile - - version = catalog.version - - fileobj = catalog.vertices.find { |r| r.title == file } - assert(fileobj, "File was not in catalog") - - - assert_equal( - "original text\n", fileobj["content"], - - "Template did not work") - - Puppet[:filetimeout] = -5 - # Have to sleep because one second is the fs's time granularity. - sleep(1) - - # Now modify the template - File.open(template, "w") do |f| - f.puts "new text" - end - - newversion = Puppet::Parser::Compiler.new(node).compile.version - - assert(version != newversion, "Parse date did not change") - end - - def test_template_defined_vars - template = tempfile - - File.open(template, "w") do |f| - f.puts "template <%= @yayness %>" - end - - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => "template", - :ftype => :rvalue, - - :arguments => AST::ASTArray.new( - :children => [stringobj(template)] - ) - ) - end - ast = varobj("output", func) - - { - "" => "", - false => "false", - }.each do |string, value| - scope = mkscope - scope['yayness'] = string - assert_equal(scope['yayness'], string, "did not correctly evaluate '#{string}'") - - assert_nothing_raised("An empty string was not a valid variable value") do - ast.evaluate(scope) - end - - assert_equal( - "template #{value}\n", scope['output'], - "#{string.inspect} did not get evaluated correctly") - end - end - - def test_autoloading_functions - #assert_equal(false, Puppet::Parser::Functions.function(:autofunc), - # "Got told autofunc already exists") - - dir = tempfile - $LOAD_PATH << dir - newpath = File.join(dir, "puppet", "parser", "functions") - FileUtils.mkdir_p(newpath) - - File.open(File.join(newpath, "autofunc.rb"), "w") { |f| - f.puts %{ - Puppet::Parser::Functions.newfunction(:autofunc, :type => :rvalue) do |vals| - Puppet.wanring vals.inspect - end - } - } - Puppet::Node::Environment.stubs(:current).returns nil - obj = nil - assert_nothing_raised { - obj = Puppet::Parser::Functions.function(:autofunc) - } - - assert(obj, "Did not autoload function") - assert(Puppet::Parser::Functions.environment_module.method_defined?(:function_autofunc), "Did not set function correctly") - end - - def test_search - scope = mkscope - - fun = scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "yay::ness") - foo = scope.known_resource_types.add Puppet::Resource::Type.new(:definition, "foo::bar") - - search = Puppet::Parser::Functions.function(:search) - scope.function_search(["foo", "yay"]) - - ffun = ffoo = nil - assert_nothing_raised("Search path change did not work") do - ffun = scope.find_definition("ness") - ffoo = scope.find_definition('bar') - end - - assert(ffun, "Could not find definition in 'fun' namespace") - assert(ffoo, "Could not find definition in 'foo' namespace") - end - - def test_include - scope = mkscope - parser = mkparser - - include = Puppet::Parser::Functions.function(:include) - - assert_raise(Puppet::Error, "did not throw error on missing class") do - scope.function_include("nosuchclass") - end - - scope.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "myclass", {}) - - scope.compiler.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass}) - - assert_nothing_raised do - scope.function_include(["myclass", "otherclass"]) - end - end - - def test_file - parser = mkparser - scope = mkscope(:parser => parser) - - file = Puppet::Parser::Functions.function(:file) - - file1 = tempfile - file2 = tempfile - file3 = tempfile - - File.open(file2, "w") { |f| f.puts "yaytest" } - - val = nil - assert_nothing_raised("Failed to call file with one arg") do - val = scope.function_file([file2]) - end - - assert_equal("yaytest\n", val, "file() failed") - - assert_nothing_raised("Failed to call file with two args") do - val = scope.function_file([file1, file2]) - end - - assert_equal("yaytest\n", val, "file() failed") - - assert_raise(Puppet::ParseError, "did not fail when files are missing") do - val = scope.function_file([file1, file3]) - end - end - - def test_generate - command = tempfile - sh = %x{which sh} - File.open(command, "w") do |f| - f.puts %{#!#{sh} - if [ -n "$1" ]; then - echo "yay-$1" - else - echo yay - fi - } - end - File.chmod(0755, command) - assert_equal("yay\n", %x{#{command}}, "command did not work") - assert_equal("yay-foo\n", %x{#{command} foo}, "command did not work") - - Puppet::Node::Environment.stubs(:current).returns nil - generate = Puppet::Parser::Functions.function(:generate) - - scope = mkscope - parser = mkparser - - val = nil - assert_nothing_raised("Could not call generator with no args") do - val = scope.function_generate([command]) - end - assert_equal("yay\n", val, "generator returned wrong results") - - assert_nothing_raised("Could not call generator with args") do - val = scope.function_generate([command, "foo"]) - end - assert_equal("yay-foo\n", val, "generator returned wrong results") - - assert_raise(Puppet::ParseError, "Did not fail with an unqualified path") do - val = scope.function_generate([File.basename(command), "foo"]) - end - - assert_raise(Puppet::ParseError, "Did not fail when command failed") do - val = scope.function_generate([%x{which touch}.chomp, "/this/dir/does/not/exist"]) - end - - fake = File.join(File.dirname(command), "..") - dir = File.dirname(command) - dirname = File.basename(dir) - bad = File.join(dir, "..", dirname, File.basename(command)) - assert_raise(Puppet::ParseError, "Did not fail when command failed") do - val = scope.function_generate([bad]) - end - end -end - diff --git a/test/language/parser.rb b/test/language/parser.rb deleted file mode 100755 index f7e636add..000000000 --- a/test/language/parser.rb +++ /dev/null @@ -1,738 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'mocha' -require 'puppet' -require 'puppet/parser/parser' -require 'puppettest' -require 'puppettest/support/utils' - -class TestParser < Test::Unit::TestCase - include PuppetTest - include PuppetTest::ParserTesting - include PuppetTest::Support::Utils - def setup - super - #@lexer = Puppet::Parser::Lexer.new - end - - def teardown - super - Puppet::Node::Environment.clear - end - - def test_each_file - textfiles { |file| - Puppet::Node::Environment.clear - parser = mkparser - Puppet.debug("parsing #{file}") if __FILE__ == $0 - assert_nothing_raised { - parser.file = file - parser.parse - } - } - end - - def test_failers - failers { |file| - parser = mkparser - Puppet.debug("parsing failer #{file}") if __FILE__ == $0 - assert_raise(Puppet::ParseError, Puppet::Error, "Did not fail while parsing #{file}") { - Puppet[:manifest] = file - config = mkcompiler(parser) - config.compile - #ast.hostclass("").evaluate config.topscope - } - } - end - - def test_arrayrvalues - parser = mkparser - ret = nil - file = tempfile - assert_nothing_raised { - parser.string = "file { \"#{file}\": mode => [755, 640] }" - } - - assert_nothing_raised { - ret = parser.parse - } - end - - def test_arrayrvalueswithtrailingcomma - parser = mkparser - ret = nil - file = tempfile - assert_nothing_raised { - parser.string = "file { \"#{file}\": mode => [755, 640,] }" - } - - assert_nothing_raised { - ret = parser.parse - } - end - - def mkmanifest(file) - name = File.join(tmpdir, "file#{rand(100)}") - @@tmpfiles << name - - File.open(file, "w") { |f| - f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % name - } - end - - def test_importglobbing - basedir = File.join(tmpdir, "importesting") - @@tmpfiles << basedir - Dir.mkdir(basedir) - - subdir = "subdir" - Dir.mkdir(File.join(basedir, subdir)) - manifest = File.join(basedir, "manifest") - File.open(manifest, "w") { |f| - f.puts "import \"%s/*\"" % subdir - } - - 4.times { |i| - path = File.join(basedir, subdir, "subfile#{i}.pp") - mkmanifest(path) - } - - assert_nothing_raised("Could not parse multiple files") { - parser = mkparser - parser.file = manifest - parser.parse - } - end - - def test_nonexistent_import - basedir = File.join(tmpdir, "importesting") - @@tmpfiles << basedir - Dir.mkdir(basedir) - manifest = File.join(basedir, "manifest") - File.open(manifest, "w") do |f| - f.puts "import \" no such file \"" - end - assert_raise(Puppet::ParseError) { - parser = mkparser - parser.file = manifest - parser.parse - } - end - - def test_trailingcomma - path = tempfile - str = %{file { "#{path}": ensure => file, } - } - - parser = mkparser - parser.string = str - - assert_nothing_raised("Could not parse trailing comma") { - parser.parse - } - end - - def test_importedclasses - imported = tempfile '.pp' - importer = tempfile '.pp' - - made = tempfile - - File.open(imported, "w") do |f| - f.puts %{class foo { file { "#{made}": ensure => file }}} - end - - File.open(importer, "w") do |f| - f.puts %{import "#{imported}"\ninclude foo} - end - - parser = mkparser - parser.file = importer - - # Make sure it parses fine - assert_nothing_raised { - parser.parse - } - - # Now make sure it actually does the work - assert_creates(importer, made) - end - - # Make sure fully qualified and unqualified files can be imported - def test_fqfilesandlocalfiles - dir = tempfile - Dir.mkdir(dir) - importer = File.join(dir, "site.pp") - fullfile = File.join(dir, "full.pp") - localfile = File.join(dir, "local.pp") - - files = [] - - File.open(importer, "w") do |f| - f.puts %{import "#{fullfile}"\ninclude full\nimport "local.pp"\ninclude local} - end - - fullmaker = tempfile - files << fullmaker - - File.open(fullfile, "w") do |f| - f.puts %{class full { file { "#{fullmaker}": ensure => file }}} - end - - localmaker = tempfile - files << localmaker - - File.open(localfile, "w") do |f| - f.puts %{class local { file { "#{localmaker}": ensure => file }}} - end - - parser = mkparser - parser.file = importer - - # Make sure it parses - assert_nothing_raised { - parser.parse - } - - # Now make sure it actually does the work - assert_creates(importer, *files) - end - - # Make sure the parser adds '.pp' when necessary - def test_addingpp - dir = tempfile - Dir.mkdir(dir) - importer = File.join(dir, "site.pp") - localfile = File.join(dir, "local.pp") - - files = [] - - File.open(importer, "w") do |f| - f.puts %{import "local"\ninclude local} - end - - file = tempfile - files << file - - File.open(localfile, "w") do |f| - f.puts %{class local { file { "#{file}": ensure => file }}} - end - - parser = mkparser - parser.file = importer - - assert_nothing_raised { - parser.parse - } - end - - # Make sure that file importing changes file relative names. - def test_changingrelativenames - dir = tempfile - Dir.mkdir(dir) - Dir.mkdir(File.join(dir, "subdir")) - top = File.join(dir, "site.pp") - subone = File.join(dir, "subdir/subone") - subtwo = File.join(dir, "subdir/subtwo") - - files = [] - file = tempfile - files << file - - File.open(subone + ".pp", "w") do |f| - f.puts %{class one { file { "#{file}": ensure => file }}} - end - - otherfile = tempfile - files << otherfile - File.open(subtwo + ".pp", "w") do |f| - f.puts %{import "subone"\n class two inherits one { - file { "#{otherfile}": ensure => file } - }} - end - - File.open(top, "w") do |f| - f.puts %{import "subdir/subtwo"} - end - - parser = mkparser - parser.file = top - - assert_nothing_raised { - parser.parse - } - end - - # Defaults are purely syntactical, so it doesn't make sense to be able to - # collect them. - def test_uncollectabledefaults - string = "@Port { protocols => tcp }" - - assert_raise(Puppet::ParseError) { - mkparser.parse(string) - } - end - - # Verify that we can parse collections - def test_collecting - text = "Port <| |>" - parser = mkparser - parser.string = text - - ret = nil - assert_nothing_raised { - ret = parser.parse - } - - ret.code.each do |obj| - assert_instance_of(AST::Collection, obj) - end - end - - def test_emptyfile - file = tempfile - File.open(file, "w") do |f| - f.puts %{} - end - parser = mkparser - parser.file = file - assert_nothing_raised { - parser.parse - } - end - - def test_multiple_nodes_named - file = tempfile - other = tempfile - - File.open(file, "w") do |f| - f.puts %{ -node nodeA, nodeB { - file { "#{other}": ensure => file } - -} -} - end - - parser = mkparser - parser.file = file - ast = nil - assert_nothing_raised { - ast = parser.parse - } - end - - def test_emptyarrays - str = %{$var = []\n} - - parser = mkparser - parser.string = str - - # Make sure it parses fine - assert_nothing_raised { - parser.parse - } - end - - # Make sure function names aren't reserved words. - def test_functionnamecollision - str = %{tag yayness -tag(rahness) - -file { "/tmp/yayness": - tag => "rahness", - ensure => exists -} -} - parser = mkparser - parser.string = str - - # Make sure it parses fine - assert_nothing_raised { - parser.parse - } - end - - def test_metaparams_in_definition_prototypes - parser = mkparser - - - assert_raise(Puppet::ParseError) { - parser.known_resource_types.import_ast(parser.parse(%{define mydef($schedule) {}}), '') - } - - assert_nothing_raised { - parser.known_resource_types.import_ast(parser.parse(%{define adef($schedule = false) {}}), '') - parser.known_resource_types.import_ast(parser.parse(%{define mydef($schedule = daily) {}}), '') - } - end - - def test_parsingif - parser = mkparser - exec = proc do |val| - %{exec { "/bin/echo #{val}": logoutput => true }} - end - str1 = %{if true { #{exec.call("true")} }} - ret = nil - assert_nothing_raised { - ret = parser.parse(str1).code[0] - } - assert_instance_of(Puppet::Parser::AST::IfStatement, ret) - parser = mkparser - str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }} - ret = parser.parse(str2).code[0] - assert_instance_of(Puppet::Parser::AST::IfStatement, ret) - assert_instance_of(Puppet::Parser::AST::Else, ret.else) - end - - def test_hostclass - parser = mkparser - - assert_nothing_raised { - parser.known_resource_types.import_ast(parser.parse(%{class myclass { class other {} }}), '') - } - assert(parser.hostclass("myclass"), "Could not find myclass") - assert(parser.hostclass("myclass::other"), "Could not find myclass::other") - - assert_nothing_raised { - parser.known_resource_types.import_ast(parser.parse("class base {} - class container { - class deep::sub inherits base {} - }"), '') - } - sub = parser.hostclass("container::deep::sub") - assert(sub, "Could not find sub") - - # Now try it with a parent class being a fq class - assert_nothing_raised { - parser.known_resource_types.import_ast(parser.parse("class container::one inherits container::deep::sub {}"), '') - } - sub = parser.hostclass("container::one") - assert(sub, "Could not find one") - assert_equal("container::deep::sub", sub.parent) - - # Finally, try including a qualified class - assert_nothing_raised("Could not include fully qualified class") { - parser.known_resource_types.import_ast(parser.parse("include container::deep::sub"), '') - } - end - - def test_topnamespace - parser = mkparser - - # Make sure we put the top-level code into a class called "" in - # the "" namespace - parser.initvars - assert_nothing_raised do - parser.known_resource_types.import_ast(parser.parse("Exec { path => '/usr/bin:/usr/sbin' }"), '') - assert_equal("", parser.known_resource_types.hostclass("").name) - assert_equal("", parser.known_resource_types.hostclass("").namespace) - end - end - - # Make sure virtual and exported resources work appropriately. - def test_virtualresources - tests = [:virtual] - if Puppet.features.rails? - catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class - facts_cache_class = Puppet::Node::Facts.indirection.cache_class - node_cache_class = Puppet::Node.indirection.cache_class - Puppet[:storeconfigs] = true - tests << :exported - end - - tests.each do |form| - parser = mkparser - - if form == :virtual - at = "@" - else - at = "@@" - end - - check = proc do |res, msg| - if res.is_a?(Puppet::Parser::Resource) - txt = res.ref - else - txt = res.class - end - # Real resources get marked virtual when exported - if form == :virtual or res.is_a?(Puppet::Parser::Resource) - assert(res.virtual, "#{msg} #{at}#{txt} is not virtual") - end - if form == :virtual - assert(! res.exported, "#{msg} #{at}#{txt} is exported") - else - assert(res.exported, "#{msg} #{at}#{txt} is not exported") - end - end - - ret = nil - assert_nothing_raised do - parser.known_resource_types.import_ast(parser.parse("#{at}file { '/tmp/testing': owner => root }"), '') - ret = parser.known_resource_types - end - - assert_instance_of(AST::ASTArray, ret.hostclass("").code) - resdef = ret.hostclass("").code[0] - assert_instance_of(AST::Resource, resdef) - assert_instance_of(AST::ASTArray, resdef.instances) - assert_equal(1, resdef.instances.children.length) - assert_equal("/tmp/testing", resdef.instances[0].title.value) - # We always get an astarray back, so... - check.call(resdef, "simple resource") - - # Now let's try it with multiple resources in the same spec - assert_nothing_raised do - parser.known_resource_types.import_ast(parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }"), '') - ret = parser.known_resource_types - end - - ret.hostclass("").code[0].each do |res| - assert_instance_of(AST::Resource, res) - check.call(res, "multiresource") - end - end - - ensure - if Puppet.features.rails? - Puppet[:storeconfigs] = false - Puppet::Resource::Catalog.indirection.cache_class = catalog_cache_class - Puppet::Node::Facts.indirection.cache_class = facts_cache_class - Puppet::Node.indirection.cache_class = node_cache_class - end - end - - def test_collections - tests = [:virtual] - if Puppet.features.rails? - catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class - facts_cache_class = Puppet::Node::Facts.indirection.cache_class - node_cache_class = Puppet::Node.indirection.cache_class - Puppet[:storeconfigs] = true - tests << :exported - end - - tests.each do |form| - Puppet::Node::Environment.clear - parser = mkparser - - if form == :virtual - arrow = "<||>" - else - arrow = "<<||>>" - end - - ret = nil - assert_nothing_raised do - ret = parser.parse("File #{arrow}") - end - - coll = ret.code[0] - assert_instance_of(AST::Collection, coll) - assert_equal(form, coll.form) - end - - ensure - if Puppet.features.rails? - Puppet[:storeconfigs] = false - Puppet::Resource::Catalog.indirection.cache_class = catalog_cache_class - Puppet::Node::Facts.indirection.cache_class = facts_cache_class - Puppet::Node.indirection.cache_class = node_cache_class - end - end - - def test_collectionexpressions - %w{== !=}.each do |oper| - Puppet::Node::Environment.clear - str = "File <| title #{oper} '/tmp/testing' |>" - - parser = mkparser - - res = nil - assert_nothing_raised do - res = parser.parse(str).code[0] - end - - assert_instance_of(AST::Collection, res) - - query = res.query - assert_instance_of(AST::CollExpr, query) - - assert_equal(:virtual, query.form) - assert_equal("title", query.test1.value) - assert_equal("/tmp/testing", query.test2.value) - assert_equal(oper, query.oper) - end - end - - def test_collectionstatements - %w{and or}.each do |joiner| - str = "File <| title == '/tmp/testing' #{joiner} owner == root |>" - - parser = mkparser - - res = nil - assert_nothing_raised do - res = parser.parse(str).code[0] - end - - assert_instance_of(AST::Collection, res) - - query = res.query - assert_instance_of(AST::CollExpr, query) - - assert_equal(joiner, query.oper) - assert_instance_of(AST::CollExpr, query.test1) - assert_instance_of(AST::CollExpr, query.test2) - end - end - - def test_collectionstatements_with_parens - [ - "(title == '/tmp/testing' and owner == root) or owner == wheel", - "(title == '/tmp/testing')" - ].each do |test| - str = "File <| #{test} |>" - parser = mkparser - - res = nil - assert_nothing_raised("Could not parse '#{test}'") do - res = parser.parse(str).code[0] - end - - assert_instance_of(AST::Collection, res) - - query = res.query - assert_instance_of(AST::CollExpr, query) - - #assert_equal(joiner, query.oper) - #assert_instance_of(AST::CollExpr, query.test1) - #assert_instance_of(AST::CollExpr, query.test2) - end - end - - def test_fully_qualified_definitions - parser = mkparser - - types = parser.known_resource_types - assert_nothing_raised("Could not parse fully-qualified definition") { - types.import_ast(parser.parse(%{define one::two { }}), '') - } - assert(parser.definition("one::two"), "Could not find one::two with no namespace") - end - - # #524 - def test_functions_with_no_arguments - parser = mkparser - assert_nothing_raised("Could not parse statement function with no args") { - parser.parse %{tag()} - } - assert_nothing_raised("Could not parse rvalue function with no args") { - parser.parse %{$testing = template()} - } - end - - # #774 - def test_fully_qualified_collection_statement - parser = mkparser - assert_nothing_raised("Could not parse fully qualified collection statement") { - parser.parse %{Foo::Bar <||>} - } - end - - def test_multiple_imports_on_one_line - one = tempfile '.pp' - two = tempfile '.pp' - base = tempfile '.pp' - File.open(one, "w") { |f| f.puts "$var = value" } - File.open(two, "w") { |f| f.puts "$var = value" } - File.open(base, "w") { |f| f.puts "import '#{one}', '#{two}'" } - - parser = mkparser - parser.file = base - - # Importing is logged at debug time. - Puppet::Util::Log.level = :debug - assert_nothing_raised("Parser could not import multiple files at once") do - parser.parse - end - - [one, two].each do |file| - assert(@logs.detect { |l| l.message =~ /importing '#{file}'/}, "did not import #{file}") - end - end - - def test_cannot_assign_qualified_variables - parser = mkparser - assert_raise(Puppet::ParseError, "successfully assigned a qualified variable") do - parser.parse("$one::two = yay") - end - end - - # #629 - undef keyword - def test_undef - parser = mkparser - result = nil - assert_nothing_raised("Could not parse assignment to undef") { - result = parser.parse %{$variable = undef} - } - - main = result.code - children = main.children - assert_instance_of(AST::VarDef, main.children[0]) - assert_instance_of(AST::Undef, main.children[0].value) - end - - # Prompted by #729 -- parsing should not modify the interpreter. - def test_parse - parser = mkparser - - str = "file { '/tmp/yay': ensure => file }\nclass yay {}\nnode foo {}\ndefine bar {}\n" - result = nil - assert_nothing_raised("Could not parse") do - parser.known_resource_types.import_ast(parser.parse(str), '') - result = parser.known_resource_types - end - assert_instance_of(Puppet::Resource::TypeCollection, result, "Did not get a ASTSet back from parsing") - - assert_instance_of(Puppet::Resource::Type, result.hostclass("yay"), "Did not create 'yay' class") - assert_instance_of(Puppet::Resource::Type, result.hostclass(""), "Did not create main class") - assert_instance_of(Puppet::Resource::Type, result.definition("bar"), "Did not create 'bar' definition") - assert_instance_of(Puppet::Resource::Type, result.node("foo"), "Did not create 'foo' node") - end - - def test_namesplit - parser = mkparser - - assert_nothing_raised do - {"base::sub" => %w{base sub}, - "main" => ["", "main"], - "one::two::three::four" => ["one::two::three", "four"], - }.each do |name, ary| - result = parser.namesplit(name) - assert_equal(ary, result, "#{name} split to #{result}") - end - end - end - - # Make sure class, node, and define methods are case-insensitive - def test_structure_case_insensitivity - parser = mkparser - - result = nil - assert_nothing_raised do - parser.known_resource_types.import_ast(parser.parse("class yayness { }"), '') - result = parser.known_resource_types.hostclass('yayness') - end - assert_equal(result, parser.find_hostclass("", "yayNess")) - - assert_nothing_raised do - parser.known_resource_types.import_ast(parser.parse("define funtest { }"), '') - result = parser.known_resource_types.definition('funtest') - end - assert_equal(result, parser.find_definition("", "fUntEst"), "#{"fUntEst"} was not matched") - end -end diff --git a/test/language/scope.rb b/test/language/scope.rb deleted file mode 100755 index c80178e7b..000000000 --- a/test/language/scope.rb +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'mocha' -require 'puppettest' -require 'puppettest/parsertesting' -require 'puppettest/resourcetesting' - -# so, what kind of things do we want to test? - -# we don't need to test function, since we're confident in the -# library tests. We do, however, need to test how things are actually -# working in the language. - -# so really, we want to do things like test that our ast is correct -# and test whether we've got things in the right scopes - -class TestScope < Test::Unit::TestCase - include PuppetTest::ParserTesting - include PuppetTest::ResourceTesting - - def setup - Puppet::Node::Environment.clear - super - end - - def to_ary(hash) - hash.collect { |key,value| - [key,value] - } - end - - def test_variables - config = mkcompiler - topscope = config.topscope - midscope = config.newscope(topscope) - botscope = config.newscope(midscope) - - scopes = {:top => topscope, :mid => midscope, :bot => botscope} - - # Set a variable in the top and make sure all three can get it - topscope['first'] = 'topval' - scopes.each do |name, scope| - assert_equal("topval", scope['first'], "Could not find var in #{name}") - end - - # Now set a var in the midscope and make sure the mid and bottom can see it but not the top - midscope['second'] = "midval" - assert_nil(scopes[:top]['second'], "Found child var in top scope") - [:mid, :bot].each do |name| - assert_equal("midval", scopes[name]['second'], "Could not find var in #{name}") - end - - # And set something in the bottom, and make sure we only find it there. - botscope['third'] = "botval" - [:top, :mid].each do |name| - assert_nil(scopes[name]['third'], "Found child var in top scope") - end - assert_equal("botval", scopes[:bot]['third'], "Could not find var in bottom scope") - - - # Test that the scopes convert to hash structures correctly. - # For topscope recursive vs non-recursive should be identical - assert_equal(topscope.to_hash(false), topscope.to_hash(true), - "Recursive and non-recursive hash is identical for topscope") - - # Check the variable we expect is present. - assert_equal({"first" => "topval"}, topscope.to_hash, "topscope returns the expected hash of variables") - - # Now, check that midscope does the right thing in all cases. - - assert_equal( - {"second" => "midval"}, - midscope.to_hash(false), - - "midscope non-recursive hash contains only midscope variable") - - assert_equal( - {"first" => "topval", "second" => "midval"}, - midscope.to_hash(true), - - "midscope recursive hash contains topscope variable also") - - # Finally, check the ability to shadow symbols by adding a shadow to - # bottomscope, then checking that we see the right stuff. - botscope['first'] = "shadowval" - - assert_equal( - {"third" => "botval", "first" => "shadowval"}, - botscope.to_hash(false), - - "botscope has the right non-recursive hash") - - assert_equal( - {"third" => "botval", "first" => "shadowval", "second" => "midval"}, - botscope.to_hash(true), - - "botscope values shadow parent scope values") - end - - def test_declarative - # set to declarative - top = mkscope - sub = mkscope(:parent => top) - - assert_nothing_raised { - top['test'] = "value" - } - assert_raise(Puppet::ParseError) { - top['test'] = 'other' - } - assert_nothing_raised { - top['other'] = 'later' - } - assert_raise(Puppet::ParseError) { - top['other'] = 'yeehaw' - } - end - - def test_parent - config = mkcompiler - top = config.topscope - - # Make a subscope - sub = config.newscope(top) - - assert_equal(top, sub.parent, "Did not find parent scope correctly") - assert_equal(top, sub.parent, "Did not find parent scope on second call") - end - - # Make sure we know what we consider to be truth. - def test_truth - - assert_equal( - true, Puppet::Parser::Scope.true?("a string"), - - "Strings not considered true") - - assert_equal( - true, Puppet::Parser::Scope.true?(true), - - "True considered true") - - assert_equal( - false, Puppet::Parser::Scope.true?(""), - - "Empty strings considered true") - - assert_equal( - false, Puppet::Parser::Scope.true?(false), - - "false considered true") - - assert_equal( - false, Puppet::Parser::Scope.true?(:undef), - - "undef considered true") - end - - def test_virtual_definitions_do_not_get_evaluated - parser = mkparser - config = mkcompiler - - # Create a default source - parser.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "") - config.topscope.source = parser.known_resource_types.hostclass("") - - # And a scope resource - scope_res = Puppet::Parser::Resource.new(:file, "/file", :scope => config.topscope) - config.topscope.resource = scope_res - - args = AST::ASTArray.new( - :children => [nameobj("arg")] - ) - - # Create a top-level define - parser.known_resource_types.add Puppet::Resource::Type.new(:definition, "one", :arguments => [%w{arg}], - :code => AST::ASTArray.new( - :children => [ - resourcedef("file", "/tmp", {"owner" => varref("arg")}) - ] - )) - - # create a resource that calls our third define - obj = resourcedef("one", "boo", {"arg" => "parentfoo"}) - - # And mark it as virtual - obj.virtual = true - - # And then evaluate it - obj.evaluate config.topscope - - # And run the loop. - config.send(:evaluate_generators) - - %w{File}.each do |type| - objects = config.resources.find_all { |r| r.type == type and r.virtual } - - assert(objects.empty?, "Virtual define got evaluated") - end - end - - if defined? ::ActiveRecord - # Verify that we can both store and collect an object in the same - # run, whether it's in the same scope as a collection or a different - # scope. - def test_storeandcollect - catalog_cache_class = Puppet::Resource::Catalog.indirection.cache_class - facts_cache_class = Puppet::Node::Facts.indirection.cache_class - node_cache_class = Puppet::Node.indirection.cache_class - Puppet[:storeconfigs] = true - Puppet::Rails.init - sleep 1 - children = [] - Puppet[:code] = " -class yay { - @@host { myhost: ip => \"192.168.0.2\" } -} -include yay -@@host { puppet: ip => \"192.168.0.3\" } -Host <<||>>" - - config = nil - # We run it twice because we want to make sure there's no conflict - # if we pull it up from the database. - node = mknode - node.merge "hostname" => node.name - 2.times { |i| - catalog = Puppet::Parser::Compiler.new(node).compile - assert_instance_of(Puppet::Parser::Resource, catalog.resource(:host, "puppet")) - assert_instance_of(Puppet::Parser::Resource, catalog.resource(:host, "myhost")) - } - ensure - Puppet[:storeconfigs] = false - Puppet::Resource::Catalog.indirection.cache_class = catalog_cache_class - Puppet::Node::Facts.indirection.cache_class = facts_cache_class - Puppet::Node.indirection.cache_class = node_cache_class - end - else - $stderr.puts "No ActiveRecord -- skipping collection tests" - end - - def test_namespaces - scope = mkscope - - - assert_equal( - [""], scope.namespaces, - - "Started out with incorrect namespaces") - assert_nothing_raised { scope.add_namespace("fun::test") } - assert_equal(["fun::test"], scope.namespaces, "Did not add namespace correctly") - assert_nothing_raised { scope.add_namespace("yay::test") } - assert_equal(["fun::test", "yay::test"], scope.namespaces, "Did not add extra namespace correctly") - end - - # #629 - undef should be "" or :undef - def test_lookupvar_with_undef - scope = mkscope - - scope['testing'] = :undef - assert_equal(:undef, scope['testing'], "undef was not returned as :undef") - end -end - diff --git a/test/language/snippets.rb b/test/language/snippets.rb deleted file mode 100755 index 75d86ca76..000000000 --- a/test/language/snippets.rb +++ /dev/null @@ -1,503 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/parser/parser' -require 'puppettest' - -class TestSnippets < Test::Unit::TestCase - include PuppetTest - - def setup - super - @file = Puppet::Type.type(:file) - Facter.stubs(:to_hash).returns({}) - Facter.stubs(:value).returns("whatever") - end - - def self.snippetdir - PuppetTest.datadir "snippets" - end - - def assert_file(path, msg = nil) - unless file = @catalog.resource(:file, path) - msg ||= "Could not find file #{path}" - raise msg - end - end - - def assert_not_file(path, msg = nil) - if file = @catalog.resource(:file, path) - msg ||= "File #{path} exists!" - raise msg - end - end - - def assert_mode_equal(mode, path) - if mode.is_a? Integer - mode = mode.to_s(8) - end - unless file = @catalog.resource(:file, path) - raise "Could not find file #{path}" - end - - unless mode == file.should(:mode) - raise "Mode for %s is incorrect: %o vs %o" % [path, mode, file.should(:mode)] - end - end - - def snippet(name) - File.join(self.class.snippetdir, name) - end - - def file2ast(file) - parser = Puppet::Parser::Parser.new - parser.file = file - ast = parser.parse - - ast - end - - def snippet2ast(text) - parser = Puppet::Parser::Parser.new - parser.string = text - ast = parser.parse - - ast - end - - def ast2scope(ast) - scope = Puppet::Parser::Scope.new - ast.evaluate(scope) - - scope - end - - def snippet2scope(snippet) - ast = snippet2ast(snippet) - scope = ast2scope(ast) - end - - def properties(type) - properties = type.validproperties - end - - def metaparams(type) - mparams = [] - Puppet::Type.eachmetaparam { |param| - mparams.push param - } - - mparams - end - - def params(type) - params = [] - type.parameters.each { |name,property| - params.push name - } - - params - end - - def randthing(thing,type) - list = self.send(thing,type) - list[rand(list.length)] - end - - def randeach(type) - [:properties, :metaparams, :parameters].collect { |thing| - randthing(thing,type) - } - end - - @@snippets = { - true => [ - %{File { mode => 755 }} - ], - } - - def disabled_test_defaults - Puppet::Type.eachtype { |type| - next if type.name == :puppet or type.name == :component - - rands = randeach(type) - - name = type.name.to_s.capitalize - - [0..1, 0..2].each { |range| - params = rands[range] - paramstr = params.collect { |param| - "#{param} => fake" - }.join(", ") - - str = "#{name} { #{paramstr} }" - - scope = nil - assert_nothing_raised { - scope = snippet2scope(str) - } - - defaults = nil - assert_nothing_raised { - defaults = scope.lookupdefaults(name) - } - - p defaults - - params.each { |param| - puts "#{name} => '#{param}'" - assert(defaults.include?(param)) - } - } - } - end - - # this is here in case no tests get defined; otherwise we get a warning - def test_nothing - end - - def snippet_filecreate - %w{a b c d}.each { |letter| - path = "/tmp/create#{letter}test" - assert_file(path) - assert_mode_equal(0755, path) if %w{a b}.include?(letter) - } - end - - def snippet_simpledefaults - path = "/tmp/defaulttest" - assert_file(path) - assert_mode_equal(0755, path) - end - - def snippet_simpleselector - files = %w{a b c d}.collect { |letter| - path = "/tmp/snippetselect#{letter}test" - assert_file(path) - assert_mode_equal(0755, path) - } - end - - def snippet_classpathtest - path = "/tmp/classtest" - - file = @catalog.resource(:file, path) - assert(file, "did not create file #{path}") - - assert_equal( "/Stage[main]/Testing/Mytype[componentname]/File[/tmp/classtest]", file.path) - end - - def snippet_argumentdefaults - path1 = "/tmp/argumenttest1" - path2 = "/tmp/argumenttest2" - - file1 = @catalog.resource(:file, path1) - file2 = @catalog.resource(:file, path2) - - assert_file(path1) - assert_mode_equal(0755, path1) - - assert_file(path2) - assert_mode_equal(0644, path2) - end - - def snippet_casestatement - paths = %w{ - /tmp/existsfile - /tmp/existsfile2 - /tmp/existsfile3 - /tmp/existsfile4 - /tmp/existsfile5 - /tmp/existsfile6 - } - - paths.each { |path| - file = @catalog.resource(:file, path) - assert(file, "File #{path} is missing") - assert_mode_equal(0755, path) - } - end - - def snippet_implicititeration - paths = %w{a b c d e f g h}.collect { |l| "/tmp/iteration#{l}test" } - - paths.each { |path| - file = @catalog.resource(:file, path) - assert_file(path) - assert_mode_equal(0755, path) - } - end - - def snippet_multipleinstances - paths = %w{a b c}.collect { |l| "/tmp/multipleinstances#{l}" } - - paths.each { |path| - assert_file(path) - assert_mode_equal(0755, path) - - } - end - - def snippet_namevartest - file = "/tmp/testfiletest" - dir = "/tmp/testdirtest" - assert_file(file) - assert_file(dir) - assert_equal(:directory, @catalog.resource(:file, dir).should(:ensure), "Directory is not set to be a directory") - end - - def snippet_scopetest - file = "/tmp/scopetest" - assert_file(file) - assert_mode_equal(0755, file) - end - - def snippet_selectorvalues - nums = %w{1 2 3 4 5 6 7} - files = nums.collect { |n| - "/tmp/selectorvalues#{n}" - } - - files.each { |f| - assert_file(f) - assert_mode_equal(0755, f) - } - end - - def snippet_singleselector - nums = %w{1 2 3} - files = nums.collect { |n| - "/tmp/singleselector#{n}" - } - - files.each { |f| - assert_file(f) - assert_mode_equal(0755, f) - } - end - - def snippet_falsevalues - file = "/tmp/falsevaluesfalse" - assert_file(file) - end - - def disabled_snippet_classargtest - [1,2].each { |num| - file = "/tmp/classargtest#{num}" - assert_file(file) - assert_mode_equal(0755, file) - } - end - - def snippet_classheirarchy - [1,2,3].each { |num| - file = "/tmp/classheir#{num}" - assert_file(file) - assert_mode_equal(0755, file) - } - end - - def snippet_singleary - [1,2,3,4].each { |num| - file = "/tmp/singleary#{num}" - assert_file(file) - } - end - - def snippet_classincludes - [1,2,3].each { |num| - file = "/tmp/classincludes#{num}" - assert_file(file) - assert_mode_equal(0755, file) - } - end - - def snippet_componentmetaparams - ["/tmp/component1", "/tmp/component2"].each { |file| - assert_file(file) - } - end - - def snippet_aliastest - %w{/tmp/aliastest /tmp/aliastest2 /tmp/aliastest3}.each { |file| - assert_file(file) - } - end - - def snippet_singlequote - { 1 => 'a $quote', - 2 => 'some "\yayness\"' - }.each { |count, str| - path = "/tmp/singlequote#{count}" - assert_file(path) - assert_equal(str, @catalog.resource(:file, path).parameter(:content).actual_content) - } - end - - # There's no way to actually retrieve the list of classes from the - # transaction. - def snippet_tag - end - - # Make sure that set tags are correctly in place, yo. - def snippet_tagged - tags = {"testing" => true, "yayness" => false, - "both" => false, "bothtrue" => true, "define" => true} - - tags.each do |tag, retval| - assert_file("/tmp/tagged#{tag}#{retval.to_s}") - end - end - - def snippet_defineoverrides - file = "/tmp/defineoverrides1" - assert_file(file) - assert_mode_equal(0755, file) - end - - def snippet_deepclassheirarchy - 5.times { |i| - i += 1 - file = "/tmp/deepclassheir#{i}" - assert_file(file) - } - end - - def snippet_emptyclass - # There's nothing to check other than that it works - end - - def snippet_emptyexec - assert(@catalog.resource(:exec, "touch /tmp/emptyexectest"), "Did not create exec") - end - - def snippet_multisubs - path = "/tmp/multisubtest" - assert_file(path) - file = @catalog.resource(:file, path) - assert_equal("{md5}5fbef65269a99bddc2106251dd89b1dc", file.should(:content), "sub2 did not override content") - assert_mode_equal(0755, path) - end - - def snippet_collection - assert_file("/tmp/colltest1") - assert_nil(@catalog.resource(:file, "/tmp/colltest2"), "Incorrectly collected file") - end - - def snippet_virtualresources - %w{1 2 3 4}.each do |num| - assert_file("/tmp/virtualtest#{num}") - end - end - - def snippet_componentrequire - %w{1 2}.each do |num| - - assert_file( - "/tmp/testing_component_requires#{num}", - - "#{num} does not exist") - end - end - - def snippet_realize_defined_types - assert_file("/tmp/realize_defined_test1") - assert_file("/tmp/realize_defined_test2") - end - - def snippet_collection_within_virtual_definitions - assert_file("/tmp/collection_within_virtual_definitions1_foo.txt") - assert_file("/tmp/collection_within_virtual_definitions2_foo2.txt") - end - - def snippet_fqparents - assert_file("/tmp/fqparent1", "Did not make file from parent class") - assert_file("/tmp/fqparent2", "Did not make file from subclass") - end - - def snippet_fqdefinition - assert_file("/tmp/fqdefinition", "Did not make file from fully-qualified definition") - end - - def snippet_subclass_name_duplication - assert_file("/tmp/subclass_name_duplication1", "Did not make first file from duplicate subclass names") - assert_file("/tmp/subclass_name_duplication2", "Did not make second file from duplicate subclass names") - end - - def snippet_funccomma - assert_file("/tmp/funccomma1", "Did not make first file from trailing function comma") - assert_file("/tmp/funccomma2", "Did not make second file from trailing function comma") - end - - def snippet_arraytrailingcomma - assert_file("/tmp/arraytrailingcomma1", "Did not make first file from array") - assert_file("/tmp/arraytrailingcomma2", "Did not make second file from array") - end - - def snippet_multipleclass - assert_file("/tmp/multipleclassone", "one") - assert_file("/tmp/multipleclasstwo", "two") - end - - def snippet_multilinecomments - assert_not_file("/tmp/multilinecomments","Did create a commented resource"); - end - - def snippet_collection_override - path = "/tmp/collection" - assert_file(path) - assert_mode_equal(0600, path) - end - - def snippet_ifexpression - assert_file("/tmp/testiftest","if test"); - end - - def snippet_hash - assert_file("/tmp/myhashfile1","hash test 1"); - assert_file("/tmp/myhashfile2","hash test 2"); - assert_file("/tmp/myhashfile3","hash test 3"); - assert_file("/tmp/myhashfile4","hash test 4"); - end - - # Iterate across each of the snippets and create a test. - Dir.entries(snippetdir).sort.each { |file| - next if file =~ /^\./ - - - mname = "snippet_" + file.sub(/\.pp$/, '') - if self.method_defined?(mname) - #eval("alias #{testname} #{mname}") - testname = ("test_#{mname}").intern - self.send(:define_method, testname) { - Puppet[:manifest] = snippet(file) - facts = { - "hostname" => "testhost", - "domain" => "domain.com", - "ipaddress" => "127.0.0.1", - "fqdn" => "testhost.domain.com" - } - - node = Puppet::Node.new("testhost") - node.merge(facts) - - catalog = nil - assert_nothing_raised("Could not compile catalog") { - catalog = Puppet::Resource::Catalog.indirection.find(node) - } - - assert_nothing_raised("Could not convert catalog") { - catalog = catalog.to_ral - } - - @catalog = catalog - assert_nothing_raised { - self.send(mname) - } - } - mname = mname.intern - end - } -end diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb deleted file mode 100755 index a6d1e0831..000000000 --- a/test/lib/puppettest.rb +++ /dev/null @@ -1,321 +0,0 @@ -# Add .../test/lib -testlib = File.expand_path(File.dirname(__FILE__)) -$LOAD_PATH.unshift(testlib) unless $LOAD_PATH.include?(testlib) -# Add .../lib -mainlib = File.expand_path(File.join(File.dirname(__FILE__), '../../lib')) -$LOAD_PATH.unshift(mainlib) unless $LOAD_PATH.include?(mainlib) - -require 'puppet' -require 'mocha' - -# Only load the test/unit class if we're not in the spec directory. -# Else we get the bogus 'no tests, no failures' message. -unless Dir.getwd =~ /spec/ - require 'test/unit' -end - -# Yay; hackish but it works -if ARGV.include?("-d") - ARGV.delete("-d") - $console = true -end - -require File.expand_path(File.join(File.dirname(__FILE__), '../../spec/monkey_patches/publicize_methods')) - -module PuppetTest - # These need to be here for when rspec tests use these - # support methods. - @@tmpfiles = [] - - # Munge cli arguments, so we can enable debugging if we want - # and so we can run just specific methods. - def self.munge_argv - require 'getoptlong' - - - result = GetoptLong.new( - - [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], - [ "--resolve", "-r", GetoptLong::REQUIRED_ARGUMENT ], - [ "-n", GetoptLong::REQUIRED_ARGUMENT ], - - [ "--help", "-h", GetoptLong::NO_ARGUMENT ] - ) - - usage = "USAGE: TESTOPTS='[-n -n ...] [-d]' rake [target] [target] ..." - - opts = [] - - dir = method = nil - result.each { |opt,arg| - case opt - when "--resolve" - dir, method = arg.split(",") - when "--debug" - $puppet_debug = true - Puppet::Util::Log.level = :debug - Puppet::Util::Log.newdestination(:console) - when "--help" - puts usage - exit - else - opts << opt << arg - end - } - suites = nil - - args = ARGV.dup - - # Reset the options, so the test suite can deal with them (this is - # what makes things like '-n' work). - opts.each { |o| ARGV << o } - - args - end - - # Find the root of the Puppet tree; this is not the test directory, but - # the parent of that dir. - def basedir(*list) - unless defined?(@@basedir) - Dir.chdir(File.dirname(__FILE__)) do - @@basedir = File.dirname(File.dirname(Dir.getwd)) - end - end - if list.empty? - @@basedir - else - File.join(@@basedir, *list) - end - end - - def datadir(*list) - File.join(basedir, "test", "data", *list) - end - - def exampledir(*args) - @@exampledir = File.join(basedir, "examples") unless defined?(@@exampledir) - - if args.empty? - return @@exampledir - else - return File.join(@@exampledir, *args) - end - end - - module_function :basedir, :datadir, :exampledir - - def cleanup(&block) - @@cleaners << block - end - - # Rails clobbers RUBYLIB, thanks - def libsetup - curlibs = ENV["RUBYLIB"].split(":") - $LOAD_PATH.reject do |dir| dir =~ /^\/usr/ end.each do |dir| - curlibs << dir unless curlibs.include?(dir) - end - - ENV["RUBYLIB"] = curlibs.join(":") - end - - def logcollector - collector = [] - Puppet::Util::Log.newdestination(collector) - cleanup do - Puppet::Util::Log.close(collector) - end - collector - end - - def rake? - $0 =~ /test_loader/ - end - - # Redirect stdout and stderr - def redirect - @stderr = tempfile - @stdout = tempfile - $stderr = File.open(@stderr, "w") - $stdout = File.open(@stdout, "w") - - cleanup do - $stderr = STDERR - $stdout = STDOUT - end - end - - def setup - ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin") - @memoryatstart = Puppet::Util.memory - if defined?(@@testcount) - @@testcount += 1 - else - @@testcount = 0 - end - - - @configpath = File.join( - tmpdir, - "configdir" + @@testcount.to_s + "/" - ) - - unless defined? $user and $group - $user = nonrootuser.uid.to_s - $group = nonrootgroup.gid.to_s - end - - Puppet.settings.clear - Puppet[:user] = $user - Puppet[:group] = $group - - - Puppet.settings.set_value(:name, "unittest", :application_defaults) - Puppet[:confdir] = @configpath - Puppet[:vardir] = @configpath - Puppet[:logdir] = @configpath - Puppet[:rundir] = @configpath - - Dir.mkdir(@configpath) unless File.exists?(@configpath) - - @@tmpfiles << @configpath << tmpdir - @@tmppids = [] - - @@cleaners = [] - - @logs = [] - - # If we're running under rake, then disable debugging and such. - #if rake? or ! Puppet[:debug] - #if defined?($puppet_debug) or ! rake? - Puppet[:color] = false if textmate? - Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs)) - if defined? $console - Puppet.info @method_name - Puppet::Util::Log.newdestination(:console) - Puppet[:trace] = true - end - Puppet::Util::Log.level = :debug - #$VERBOSE = 1 - #else - # Puppet::Util::Log.close - # Puppet::Util::Log.newdestination(@logs) - # Puppet[:httplog] = tempfile - #end - - Puppet[:ignoreschedules] = true - - #@start = Time.now - - #Facter.stubs(:value).returns "stubbed_value" - #Facter.stubs(:to_hash).returns({}) - end - - def tempfile(suffix = '') - if defined?(@@tmpfilenum) - @@tmpfilenum += 1 - else - @@tmpfilenum = 1 - end - - f = File.join(self.tmpdir, "tempfile_" + @@tmpfilenum.to_s + suffix) - @@tmpfiles ||= [] - @@tmpfiles << f - f - end - - def textmate? - !!ENV["TM_FILENAME"] - end - - def tstdir - dir = tempfile - Dir.mkdir(dir) - dir - end - - def tmpdir - unless @tmpdir - @tmpdir = case Facter["operatingsystem"].value - when "Darwin" then "/private/tmp" - when "SunOS" then "/var/tmp" - else - "/tmp" - end - - - @tmpdir = File.join(@tmpdir, "puppettesting#{Process.pid}") - - unless File.exists?(@tmpdir) - FileUtils.mkdir_p(@tmpdir) - File.chmod(01777, @tmpdir) - end - end - @tmpdir - end - - def remove_tmp_files - @@tmpfiles.each { |file| - unless file =~ /tmp/ - puts "Not deleting tmpfile #{file}" - next - end - if FileTest.exists?(file) - system("chmod -R 755 #{file}") - system("rm -rf #{file}") - end - } - @@tmpfiles.clear - end - - def teardown - #@stop = Time.now - #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] } - @@cleaners.each { |cleaner| cleaner.call } - - remove_tmp_files - - @@tmppids.each { |pid| - %x{kill -INT #{pid} 2>/dev/null} - } - - @@tmppids.clear - - Puppet::Util::Storage.clear - Puppet.clear - Puppet.settings.clear - - @memoryatend = Puppet::Util.memory - diff = @memoryatend - @memoryatstart - - Puppet.info "#{self.class}##{@method_name} memory growth (#{@memoryatstart} to #{@memoryatend}): #{diff}" if diff > 1000 - - # reset all of the logs - Puppet::Util::Log.close_all - @logs.clear - - # Just in case there are processes waiting to die... - require 'timeout' - - begin - Timeout::timeout(5) do - Process.waitall - end - rescue Timeout::Error - # just move on - end - end - - def logstore - @logs = [] - Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs)) - end -end - -require 'puppettest/support' -require 'puppettest/filetesting' -require 'puppettest/fakes' -require 'puppettest/exetest' -require 'puppettest/parsertesting' -require 'puppettest/servertest' -require 'puppettest/testcase' - diff --git a/test/lib/puppettest/certificates.rb b/test/lib/puppettest/certificates.rb deleted file mode 100644 index a1d8a7784..000000000 --- a/test/lib/puppettest/certificates.rb +++ /dev/null @@ -1,74 +0,0 @@ -# Certificate-related helper methods. - -require 'puppettest' - -module PuppetTest::Certificates - include PuppetTest - - def mkPassFile() - keyfile = File.join(@dir, "tmpkeyfile") - @@tmpfiles << keyfile - system("mkdir -p #{@dir}") unless FileTest.exists?(@dir) - File.open(keyfile, "w", 0600) { |f| - f.print "as;dklj23rlkjzdflij23wr" - } - - keyfile - end - - def mkCA - # The defaults make tests that consume this very slow. - Puppet[:req_bits] = 512 - Puppet[:keylength] = 512 - - ca = nil - assert_nothing_raised { - ca = Puppet::SSLCertificates::CA.new - } - - ca - end - - def mkStore(ca) - # The defaults make tests that consume this very slow. - Puppet[:req_bits] = 512 - Puppet[:keylength] = 512 - - store = OpenSSL::X509::Store.new - store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT - store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK - store.add_cert(ca.cert) - store.add_crl(ca.crl) - store - end - - def mkcert(hostname) - # The defaults make tests that consume this very slow. - Puppet[:req_bits] = 512 - Puppet[:keylength] = 512 - - cert = nil - assert_nothing_raised { - cert = Puppet::SSLCertificates::Certificate.new(:name => hostname) - cert.mkcsr - } - - cert - end - - def mksignedcert(ca = nil, hostname = nil) - # The defaults make tests that consume this very slow. - Puppet[:req_bits] = 512 - Puppet[:keylength] = 512 - - ca ||= mkCA() - hostname ||= "ttltest.example.com" - - cert = nil - assert_nothing_raised { - cert, cacert = ca.sign(mkcert(hostname).mkcsr) - } - cert - end -end - diff --git a/test/lib/puppettest/exetest.rb b/test/lib/puppettest/exetest.rb deleted file mode 100644 index 09626ff0d..000000000 --- a/test/lib/puppettest/exetest.rb +++ /dev/null @@ -1,125 +0,0 @@ -require 'puppettest/servertest' - -module PuppetTest::ExeTest - include PuppetTest::ServerTest - - def setup - super - setbindir - setlibdir - end - - def bindir - File.join(basedir, "bin") - end - - def sbindir - File.join(basedir, "sbin") - end - - def setbindir - ENV["PATH"] = [bindir, ENV["PATH"]].join(":") unless ENV["PATH"].split(":").include?(bindir) - ENV["PATH"] = [sbindir, ENV["PATH"]].join(":") unless ENV["PATH"].split(":").include?(sbindir) - end - - def setlibdir - ENV["RUBYLIB"] = $LOAD_PATH.find_all { |dir| - dir =~ /puppet/ or dir =~ /\.\./ - }.join(":") - end - - # Run a ruby command. This explicitly uses ruby to run stuff, since we - # don't necessarily know where our ruby binary is, dernit. - # Currently unused, because I couldn't get it to work. - def rundaemon(*cmd) - @ruby ||= %x{which ruby}.chomp - cmd = cmd.unshift(@ruby).join(" ") - - out = nil - Dir.chdir(bindir) { - out = %x{#{@ruby} #{cmd}} - } - out - end - - def startmasterd(args = "") - output = nil - - manifest = mktestmanifest - args += " --manifest #{manifest}" - args += " --confdir #{Puppet[:confdir]}" - args += " --rundir #{File.join(Puppet[:vardir], "run")}" - args += " --vardir #{Puppet[:vardir]}" - args += " --dns_alt_names #{Puppet[:master_dns_alt_names]}" - args += " --masterport #{@@port}" - args += " --user #{Puppet::Util::SUIDManager.uid}" - args += " --group #{Puppet::Util::SUIDManager.gid}" - args += " --autosign true" - - #if Puppet[:debug] - # args += " --debug" - #end - - cmd = "puppetmasterd #{args}" - - - assert_nothing_raised { - output = %x{#{cmd}}.chomp - } - assert_equal("", output, "Puppetmasterd produced output #{output}") - assert($CHILD_STATUS == 0, "Puppetmasterd exit status was #{$CHILD_STATUS}") - sleep(1) - - cleanup do - stopmasterd - sleep(1) - end - - manifest - end - - def stopmasterd(running = true) - ps = Facter["ps"].value || "ps -ef" - - pidfile = File.join(Puppet[:vardir], "run", "puppetmasterd.pid") - - pid = nil - if FileTest.exists?(pidfile) - pid = File.read(pidfile).chomp.to_i - File.unlink(pidfile) - end - - return unless running - if running or pid - runningpid = nil - %x{#{ps}}.chomp.split(/\n/).each { |line| - if line =~ /ruby.+puppetmasterd/ - next if line =~ /\.rb/ # skip the test script itself - next if line =~ /^puppet/ # skip masters running as 'puppet' - ary = line.sub(/^\s+/, '').split(/\s+/) - pid = ary[1].to_i - end - } - - end - - # we default to mandating that it's running, but teardown - # doesn't require that - if pid - if pid == $PID - raise Puppet::Error, "Tried to kill own pid" - end - begin - Process.kill(:INT, pid) - rescue - # ignore it - end - end - end - - def teardown - stopmasterd(false) - super - end -end - diff --git a/test/lib/puppettest/fakes.rb b/test/lib/puppettest/fakes.rb deleted file mode 100644 index 712332b74..000000000 --- a/test/lib/puppettest/fakes.rb +++ /dev/null @@ -1,199 +0,0 @@ -require File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/puppet/util')) - -module PuppetTest - # A baseclass for the faketypes. - class FakeModel - include Puppet::Util - class << self - attr_accessor :name, :realresource - @name = :fakeresource - end - - def self.key_attributes - @realresource.key_attributes - end - - def self.validproperties - Puppet::Type.type(@name).validproperties - end - - def self.validproperty?(name) - Puppet::Type.type(@name).validproperty?(name) - end - - def self.to_s - "Fake#{@name.to_s.capitalize}" - end - - def [](param) - if @realresource.attrtype(param) == :property - @is[param] - else - @params[param] - end - end - - def []=(param, value) - param = symbolize(param) - raise Puppet::DevError, "Invalid attribute #{param} for #{@realresource.name}" unless @realresource.valid_parameter?(param) - if @realresource.attrtype(param) == :property - @should[param] = value - else - @params[param] = value - end - end - - def initialize(name) - @realresource = Puppet::Type.type(self.class.name) - raise "Could not find type #{self.class.name}" unless @realresource - @is = {} - @should = {} - @params = {} - self[@realresource.key_attributes.first] = name - end - - def inspect - "#{self.class.to_s.sub(/.+::/, '')}(#{super()})" - end - - def is(param) - @is[param] - end - - def should(param) - @should[param] - end - - def to_hash - hash = @params.dup - [@is, @should].each do |h| - h.each do |p, v| - hash[p] = v - end - end - hash - end - - def name - self[:name] - end - end - - class FakeProvider - attr_accessor :resource - class << self - attr_accessor :name, :resource_type, :methods - end - - # A very low number, so these never show up as defaults via the standard - # algorithms. - def self.defaultnum - -50 - end - - # Set up methods to fake things - def self.apimethods(*ary) - @resource_type.validproperties.each do |property| - ary << property unless ary.include? property - end - attr_accessor(*ary) - - @methods = ary - end - - def self.default? - false - end - - def self.initvars - @calls = Hash.new do |hash, key| - hash[key] = 0 - end - end - - def self.source - self.name - end - - def self.supports_parameter?(param) - true - end - - def self.suitable? - true - end - - def clear - @resource = nil - end - - def initialize(resource) - @resource = resource - end - - def properties - self.class.resource_type.validproperties.inject({}) do |props, name| - props[name] = self.send(name) || :absent - props - end - end - end - - class FakeParsedProvider < FakeProvider - def hash - ret = {} - instance_variables.each do |v| - v = v.sub("@", '') - if val = self.send(v) - ret[v.intern] = val - end - end - - ret - end - - def store(hash) - hash.each do |n, v| - method = n.to_s + "=" - send(method, v) if respond_to? method - end - end - end - - @@fakeresources = {} - @@fakeproviders = {} - - def fakeresource(type, name, options = {}) - type = type.intern if type.is_a? String - unless @@fakeresources.include? type - @@fakeresources[type] = Class.new(FakeModel) - @@fakeresources[type].name = type - - resource = Puppet::Type.type(type) - raise("Could not find type #{type}") unless resource - @@fakeresources[type].realresource = resource - end - - obj = @@fakeresources[type].new(name) - options.each do |name, val| - obj[name] = val - end - obj - end - - module_function :fakeresource - - def fakeprovider(type, resource) - type = type.intern if type.is_a? String - unless @@fakeproviders.include? type - @@fakeproviders[type] = Class.new(FakeModel) do - @name = type - end - end - - @@fakeproviders[type].new(resource) - end - - module_function :fakeprovider -end - diff --git a/test/lib/puppettest/fileparsing.rb b/test/lib/puppettest/fileparsing.rb deleted file mode 100644 index bd4f9e152..000000000 --- a/test/lib/puppettest/fileparsing.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'test/unit' - -module PuppetTest::FileParsing - # Run an isomorphism test on our parsing process. - def fakedataparse(*files) - files.each do |file| - @provider.stubs(:default_target).returns(file) - - @provider.prefetch - - text = @provider.to_file(@provider.target_records(file)) - text.gsub!(/^# HEADER.+\n/, '') - - yield if block_given? - - oldlines = File.readlines(file) - newlines = text.chomp.split "\n" - oldlines.zip(newlines).each do |old, new| - if self.is_a?(Test::Unit::TestCase) - assert_equal(old.chomp.gsub(/\s+/, ''), new.gsub(/\s+/, ''), "File was not written back out correctly") - else - new.gsub(/\s+/, '').should == old.chomp.gsub(/\s+/, '') - end - end - end - end -end - diff --git a/test/lib/puppettest/filetesting.rb b/test/lib/puppettest/filetesting.rb deleted file mode 100644 index 08babfe88..000000000 --- a/test/lib/puppettest/filetesting.rb +++ /dev/null @@ -1,221 +0,0 @@ -require 'puppettest' - -module PuppetTest::FileTesting - include PuppetTest - def cycle(comp) - trans = nil - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } - end - - def randlist(list) - num = rand(4) - if num == 0 - num = 1 - end - set = [] - - ret = [] - num.times { |index| - item = list[rand(list.length)] - redo if set.include?(item) - - ret.push item - } - ret - end - - def mkranddirsandfiles(dirs = nil,files = nil,depth = 3) - return if depth < 0 - - dirs ||= %w{This Is A Set Of Directories} - - files ||= %w{and this is a set of files} - - tfiles = randlist(files) - tdirs = randlist(dirs) - - tfiles.each { |file| - File.open(file, "w") { |of| - 4.times { - of.puts rand(100) - } - } - } - - tdirs.each { |dir| - # it shouldn't already exist, but... - unless FileTest.exists?(dir) - Dir.mkdir(dir) - FileUtils.cd(dir) { - mkranddirsandfiles(dirs,files,depth - 1) - } - end - } - end - - def file_list(dir) - list = nil - FileUtils.cd(dir) { - list = %x{find . 2>/dev/null}.chomp.split(/\n/) - } - list - end - - def assert_trees_equal(fromdir,todir) - assert(FileTest.directory?(fromdir)) - assert(FileTest.directory?(todir)) - - # verify the file list is the same - fromlist = nil - FileUtils.cd(fromdir) { - fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file| - ! FileTest.readable?(file) - }.sort - } - tolist = file_list(todir).sort - - fromlist.sort.zip(tolist.sort).each { |a,b| - assert_equal(a, b, "Fromfile #{a} with length #{fromlist.length} does not match tofile #{b} with length #{tolist.length}") - } - #assert_equal(fromlist,tolist) - - # and then do some verification that the files are actually set up - # the same - checked = 0 - fromlist.each_with_index { |file,i| - fromfile = File.join(fromdir,file) - tofile = File.join(todir,file) - fromstat = File.stat(fromfile) - tostat = File.stat(tofile) - [:ftype,:gid,:mode,:uid].each { |method| - - assert_equal( - - fromstat.send(method), - - tostat.send(method) - ) - - next if fromstat.ftype == "directory" - if checked < 10 and i % 3 == 0 - from = File.open(fromfile) { |f| f.read } - to = File.open(tofile) { |f| f.read } - - assert_equal(from,to) - checked += 1 - end - } - } - end - - def random_files(dir) - checked = 0 - list = file_list(dir) - list.reverse.each_with_index { |file,i| - path = File.join(dir,file) - stat = File.stat(dir) - if checked < 10 and (i % 3) == 2 - next unless yield path - checked += 1 - end - } - end - - def delete_random_files(dir) - deleted = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - false - else - deleted << file - File.unlink(file) - true - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - - deleted - end - - def add_random_files(dir) - added = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - name = File.join(file,"file" + rand(100).to_s) - File.open(name, "w") { |f| - f.puts rand(10) - } - added << name - else - false - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - added - end - - def modify_random_files(dir) - modded = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - false - else - File.open(file, "w") { |f| - f.puts rand(10) - } - modded << name - true - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - modded - end - - def readonly_random_files(dir) - modded = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - File.new(file).chmod(0111) - else - File.new(file).chmod(0000) - end - modded << file - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - modded - end - - def conffile - exampledir("root/etc/configfile") - end -end - diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb deleted file mode 100644 index b76eaff52..000000000 --- a/test/lib/puppettest/parsertesting.rb +++ /dev/null @@ -1,366 +0,0 @@ -require 'puppettest' -require 'puppet/rails' - -module PuppetTest::ParserTesting - include PuppetTest - AST = Puppet::Parser::AST - - Compiler = Puppet::Parser::Compiler - - # A fake class that we can use for testing evaluation. - class FakeAST - attr_writer :evaluate - - def evaluated? - @evaluated - end - - def evaluate(*args) - @evaluated = true - @evaluate - end - - def initialize(val = nil) - @evaluate = val if val - end - - def reset - @evaluated = nil - end - - def safeevaluate(*args) - evaluate - end - - def evaluate_match(othervalue, scope, options={}) - value = evaluate - othervalue == value - end - end - - def astarray(*args) - AST::ASTArray.new( - :children => args - ) - end - - def mkcompiler(parser = nil) - node = mknode - Compiler.new(node) - end - - def mknode(name = nil) - require 'puppet/node' - Puppet::Node.new(name || "nodename") - end - - def mkparser - Puppet::Node::Environment.clear - Puppet::Parser::Parser.new(Puppet::Node::Environment.new) - end - - def mkscope(hash = {}) - parser ||= mkparser - compiler ||= mkcompiler - compiler.topscope.source = (parser.find_hostclass("", "") || parser.newclass("")) - - raise "Could not find source for scope" unless compiler.topscope.source - # Make the 'main' stuff - compiler.send(:evaluate_main) - compiler.topscope - end - - def classobj(name, hash = {}) - hash[:file] ||= __FILE__ - hash[:line] ||= __LINE__ - hash[:type] ||= name - AST::HostClass.new(hash) - end - - def tagobj(*names) - args = {} - newnames = names.collect do |name| - if name.is_a? AST - name - else - nameobj(name) - end - end - args[:type] = astarray(*newnames) - assert_nothing_raised("Could not create tag #{names.inspect}") { - return AST::Tag.new(args) - } - end - - def resourcedef(type, title, params) - title = stringobj(title) unless title.is_a?(AST) - instance = AST::ResourceInstance.new(:title => title, :parameters => resourceparams(params)) - assert_nothing_raised("Could not create #{type} #{title}") { - - return AST::Resource.new( - - :file => __FILE__, - :line => __LINE__, - :type => type, - :instances => AST::ASTArray.new(:children => [instance]) - ) - } - end - - def virt_resourcedef(*args) - res = resourcedef(*args) - res.virtual = true - res - end - - def resourceoverride(type, title, params) - assert_nothing_raised("Could not create #{type} #{name}") { - - return AST::ResourceOverride.new( - - :file => __FILE__, - :line => __LINE__, - :object => resourceref(type, title), - :parameters => resourceparams(params) - ) - } - end - - def resourceref(type, title) - assert_nothing_raised("Could not create #{type} #{title}") { - - return AST::ResourceReference.new( - - :file => __FILE__, - :line => __LINE__, - :type => type, - - :title => stringobj(title) - ) - } - end - - def fileobj(path, hash = {"owner" => "root"}) - assert_nothing_raised("Could not create file #{path}") { - return resourcedef("file", path, hash) - } - end - - def nameobj(name) - assert_nothing_raised("Could not create name #{name}") { - - return AST::Name.new( - - :file => tempfile, - - :line => rand(100), - :value => name - ) - } - end - - def typeobj(name) - assert_nothing_raised("Could not create type #{name}") { - - return AST::Type.new( - - :file => tempfile, - - :line => rand(100), - :value => name - ) - } - end - - def nodedef(name) - assert_nothing_raised("Could not create node #{name}") { - - return AST::NodeDef.new( - - :file => tempfile, - - :line => rand(100), - :names => nameobj(name), - - :code => AST::ASTArray.new( - - :children => [ - varobj("#{name}var", "#{name}value"), - - fileobj("/#{name}") - ] - ) - ) - } - end - - def resourceparams(hash) - assert_nothing_raised("Could not create resource instance") { - params = hash.collect { |param, value| - resourceparam(param, value) - } - - return AST::ASTArray.new( - - :file => tempfile, - - :line => rand(100), - :children => params - ) - } - end - - def resourceparam(param, value) - # Allow them to pass non-strings in - value = stringobj(value) if value.is_a?(String) - assert_nothing_raised("Could not create param #{param}") { - - return AST::ResourceParam.new( - - :file => tempfile, - - :line => rand(100), - :param => param, - :value => value - ) - } - end - - def stringobj(value) - - AST::String.new( - - :file => tempfile, - - :line => rand(100), - :value => value - ) - end - - def varobj(name, value) - value = stringobj(value) unless value.is_a? AST - assert_nothing_raised("Could not create #{name} code") { - - return AST::VarDef.new( - - :file => tempfile, - - :line => rand(100), - :name => nameobj(name), - :value => value - ) - } - end - - def varref(name) - assert_nothing_raised("Could not create #{name} variable") { - - return AST::Variable.new( - - :file => __FILE__, - :line => __LINE__, - - :value => name - ) - } - end - - def argobj(name, value) - assert_nothing_raised("Could not create #{name} compargument") { - return AST::CompArgument.new( - :children => [nameobj(name), stringobj(value)] - ) - } - end - - def defaultobj(type, params) - pary = [] - params.each { |p,v| - - pary << AST::ResourceParam.new( - - :file => __FILE__, - :line => __LINE__, - :param => p, - - :value => stringobj(v) - ) - } - - past = AST::ASTArray.new( - - :file => __FILE__, - :line => __LINE__, - - :children => pary - ) - - assert_nothing_raised("Could not create defaults for #{type}") { - - return AST::ResourceDefaults.new( - - :file => __FILE__, - :line => __LINE__, - :type => type, - - :parameters => past - ) - } - end - - def taggedobj(name, ftype = :statement) - functionobj("tagged", name, ftype) - end - - def functionobj(function, name, ftype = :statement) - func = nil - assert_nothing_raised do - - func = Puppet::Parser::AST::Function.new( - - :name => function, - :ftype => ftype, - - :arguments => AST::ASTArray.new( - :children => [nameobj(name)] - ) - ) - end - - func - end - - # This assumes no nodes - def assert_creates(manifest, *files) - oldmanifest = Puppet[:manifest] - Puppet[:manifest] = manifest - - catalog = Puppet::Parser::Compiler.new(mknode).compile.to_ral - catalog.apply - - files.each do |file| - assert(FileTest.exists?(file), "Did not create #{file}") - end - ensure - Puppet[:manifest] = oldmanifest - end - - # Take a list of AST resources, evaluate them, and return the results - def assert_evaluate(children) - top = nil - assert_nothing_raised("Could not create top object") { - top = AST::ASTArray.new( - :children => children - ) - } - - trans = nil - scope = nil - assert_nothing_raised { - scope = Puppet::Parser::Scope.new - trans = scope.evaluate(:ast => top) - } - - trans - end -end diff --git a/test/lib/puppettest/railstesting.rb b/test/lib/puppettest/railstesting.rb deleted file mode 100644 index f5666f2c4..000000000 --- a/test/lib/puppettest/railstesting.rb +++ /dev/null @@ -1,18 +0,0 @@ -module PuppetTest::RailsTesting - Parser = Puppet::Parser - AST = Puppet::Parser::AST - include PuppetTest::ParserTesting - - def teardown - super - - # If we don't clean up the connection list, then the rails - # lib will still think it's connected. - ActiveRecord::Base.clear_active_connections! if Puppet.features.rails? - end - - def railsinit - Puppet::Rails.init - end -end - diff --git a/test/lib/puppettest/reporttesting.rb b/test/lib/puppettest/reporttesting.rb deleted file mode 100644 index 54a2f6799..000000000 --- a/test/lib/puppettest/reporttesting.rb +++ /dev/null @@ -1,16 +0,0 @@ -module PuppetTest::Reporttesting - def fakereport - # Create a bunch of log messages in an array. - report = Puppet::Transaction::Report.new("apply") - - 3.times { |i| - # We have to use warning so that the logs always happen - log = Puppet.warning("Report test message #{i}") - - report << log - } - - report - end -end - diff --git a/test/lib/puppettest/resourcetesting.rb b/test/lib/puppettest/resourcetesting.rb deleted file mode 100644 index ea8bec01b..000000000 --- a/test/lib/puppettest/resourcetesting.rb +++ /dev/null @@ -1,54 +0,0 @@ -module PuppetTest::ResourceTesting - Parser = Puppet::Parser - AST = Puppet::Parser::AST - - def mkevaltest(parser = nil) - parser ||= mkparser - - @parser.newdefine( - "evaltest", - - :arguments => [%w{one}, ["two", stringobj("755")]], - - :code => resourcedef( - "file", "/tmp", - - "owner" => varref("one"), "mode" => varref("two")) - ) - end - - def mkresource(args = {}) - args[:source] ||= "source" - args[:scope] ||= mkscope - - type = args[:type] || "resource" - title = args[:title] || "testing" - args.delete(:type) - args.delete(:title) - {:source => "source", :scope => "scope"}.each do |param, value| - args[param] ||= value - end - - params = args[:parameters] || {:one => "yay", :three => "rah"} - if args[:parameters] == :none - args.delete(:parameters) - else - args[:parameters] = paramify args[:source], params - end - - Parser::Resource.new(type, title, args) - end - - def param(name, value, source) - Parser::Resource::Param.new(:name => name, :value => value, :source => source) - end - - def paramify(source, hash) - hash.collect do |name, value| - Parser::Resource::Param.new( - :name => name, :value => value, :source => source - ) - end - end -end - diff --git a/test/lib/puppettest/runnable_test.rb b/test/lib/puppettest/runnable_test.rb deleted file mode 100644 index bb8d89e27..000000000 --- a/test/lib/puppettest/runnable_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -# Manage whether a test is runnable. -module PuppetTest - module RunnableTest - # Confine this example group based on specified criteria. This can be - # a message and its related test either as a hash or as a single - # message argument and a block to be evaluated at the time the confine - # is checked. - # - # Examples: - # - # confine "Rails is not available" => Puppet.features.rails? - # - # confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 } - # - def confine(hash_or_message, &block) - hash = block_given? ? {hash_or_message => block} : hash_or_message - confines.update hash - end - - # Check all confines for a given example group, starting with any - # specified in the parent example group. If any confine test is false, - # the example group is not runnable (and will be skipped). Note: This - # is used directly by Rspec and is not intended for develper use. - # - def runnable? - return false if superclass.respond_to?(:runnable?) and not superclass.runnable? - - confines.each do |message, is_runnable| - is_runnable = is_runnable.call if is_runnable.respond_to?(:call) - messages << message unless is_runnable - end - - messages.empty? - end - - def messages; @messages ||= [] end - - private - - def confines; @confines ||= {} end - end - -end diff --git a/test/lib/puppettest/servertest.rb b/test/lib/puppettest/servertest.rb deleted file mode 100644 index 852c0ec27..000000000 --- a/test/lib/puppettest/servertest.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'puppettest' - -module PuppetTest::ServerTest - include PuppetTest - def setup - super - - if defined?(@@port) - @@port += 1 - else - @@port = 20000 - end - end - - # create a simple manifest that just creates a file - def mktestmanifest - file = File.join(Puppet[:confdir], "#{(self.class.to_s + "test")}site.pp") - #@createdfile = File.join(tmpdir, self.class.to_s + "manifesttesting" + - # "_#{@method_name}") - @createdfile = tempfile - - File.open(file, "w") { |f| - f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % @createdfile - } - - @@tmpfiles << @createdfile - @@tmpfiles << file - - file - end -end - diff --git a/test/lib/puppettest/support.rb b/test/lib/puppettest/support.rb deleted file mode 100644 index c81b5cd9d..000000000 --- a/test/lib/puppettest/support.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'puppettest' - -module PuppetTest::Support -end - -require 'puppettest/support/assertions' -require 'puppettest/support/helpers' -require 'puppettest/support/utils' diff --git a/test/lib/puppettest/support/assertions.rb b/test/lib/puppettest/support/assertions.rb deleted file mode 100644 index 758c126ce..000000000 --- a/test/lib/puppettest/support/assertions.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'puppettest/support/utils' -require 'fileutils' - -module PuppetTest - include PuppetTest::Support::Utils - def assert_logged(level, regex, msg = nil) - # Skip verifying logs that we're not supposed to send. - return unless Puppet::Util::Log.sendlevel?(level) - r = @logs.detect { |l| l.level == level and l.message =~ regex } - @logs.clear - assert(r, msg) - end - - def assert_uid_gid(uid, gid, filename) - flunk "Must be uid 0 to run these tests" unless Process.uid == 0 - - fork do - Puppet::Util::SUIDManager.gid = gid - Puppet::Util::SUIDManager.uid = uid - # FIXME: use the tempfile method from puppettest.rb - system("mkfifo #{filename}") - f = File.open(filename, "w") - f << "#{Puppet::Util::SUIDManager.uid}\n#{Puppet::Util::SUIDManager.gid}\n" - yield if block_given? - end - - # avoid a race. - true while !File.exists? filename - - f = File.open(filename, "r") - - a = f.readlines - assert_equal(uid, a[0].chomp.to_i, "UID was incorrect") - assert_equal(gid, a[1].chomp.to_i, "GID was incorrect") - FileUtils.rm(filename) - end - - def assert_events(events, *resources) - trans = nil - comp = nil - msg = nil - - raise Puppet::DevError, "Incorrect call of assert_events" unless events.is_a? Array - msg = resources.pop if resources[-1].is_a? String - - config = resources2catalog(*resources) - transaction = Puppet::Transaction.new(config) - - transaction.evaluate - newevents = transaction.events. - reject { |e| ['failure', 'audit'].include? e.status }. - collect { |e| e.name } - - assert_equal(events, newevents, "Incorrect evaluate #{msg} events") - - transaction - end - - # A simpler method that just applies what we have. - def assert_apply(*resources) - config = resources2catalog(*resources) - - events = nil - assert_nothing_raised("Failed to evaluate") { - events = config.apply.events - } - events - end -end diff --git a/test/lib/puppettest/support/helpers.rb b/test/lib/puppettest/support/helpers.rb deleted file mode 100644 index 75c699f72..000000000 --- a/test/lib/puppettest/support/helpers.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'puppettest' - -module PuppetTest - # NOTE: currently both of these will produce bogus results on Darwin due to the wonderful - # UID of nobody. - def nonrootuser - Etc.passwd { |user| - return user if user.uid != Puppet::Util::SUIDManager.uid and user.uid > 0 and user.uid < 255 - } - end - - def nonrootgroup - Etc.group { |group| - return group if group.gid != Puppet::Util::SUIDManager.gid and group.gid > 0 and group.gid < 255 - } - end -end - diff --git a/test/lib/puppettest/support/resources.rb b/test/lib/puppettest/support/resources.rb deleted file mode 100755 index d5bf98f91..000000000 --- a/test/lib/puppettest/support/resources.rb +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env ruby -module PuppetTest::Support::Resources - def tree_resource(name) - Puppet::Type.type(:file).new :title => name, :path => "/tmp/#{name}", :mode => 0755 - end - - def tree_container(name) - Puppet::Type::Component.create :name => name, :type => "yay" - end - - def treenode(config, name, *resources) - comp = tree_container name - resources.each do |resource| - resource = tree_resource(resource) if resource.is_a?(String) - config.add_edge(comp, resource) - config.add_resource resource unless config.resource(resource.ref) - end - comp - end - - def mktree - catalog = Puppet::Resource::Catalog.new do |config| - one = treenode(config, "one", "a", "b") - two = treenode(config, "two", "c", "d") - middle = treenode(config, "middle", "e", "f", two) - top = treenode(config, "top", "g", "h", middle, one) - end - - catalog - end -end diff --git a/test/lib/puppettest/support/utils.rb b/test/lib/puppettest/support/utils.rb deleted file mode 100644 index 10cfa95ee..000000000 --- a/test/lib/puppettest/support/utils.rb +++ /dev/null @@ -1,132 +0,0 @@ -module PuppetTest::Support -end -module PuppetTest::Support::Utils - def gcdebug(type) - Puppet.warning "#{type}: #{ObjectSpace.each_object(type) { |o| }}" - end - - def basedir(*list) - unless defined? @@basedir - Dir.chdir(File.dirname(__FILE__)) do - @@basedir = File.dirname(File.dirname(File.dirname(File.dirname(Dir.getwd)))) - end - end - if list.empty? - @@basedir - else - File.join(@@basedir, *list) - end - end - - def fakedata(dir,pat='*') - glob = "#{basedir}/test/#{dir}/#{pat}" - files = Dir.glob(glob,File::FNM_PATHNAME) - raise Puppet::DevError, "No fakedata matching #{glob}" if files.empty? - files - end - - def datadir(*list) - File.join(basedir, "test", "data", *list) - end - - # - # TODO: I think this method needs to be renamed to something a little more - # explanatory. - # - - # Turn a list of resources, or possibly a catalog and some resources, - # into a catalog object. - def resources2catalog(*resources) - if resources[0].is_a?(Puppet::Resource::Catalog) - config = resources.shift - resources.each { |r| config.add_resource r } unless resources.empty? - elsif resources[0].is_a?(Puppet::Type.type(:component)) - raise ArgumentError, "resource2config() no longer accpts components" - comp = resources.shift - comp.delve - else - config = Puppet::Resource::Catalog.new - resources.each { |res| config.add_resource res } - end - config - end - - # TODO: rewrite this to use the 'etc' module. - - # Define a variable that contains the name of my user. - def setme - # retrieve the user name - id = %x{id}.chomp - if id =~ /uid=\d+\(([^\)]+)\)/ - @me = $1 - else - puts id - end - raise "Could not retrieve user name; 'id' did not work" unless defined?(@me) - end - - # Define a variable that contains a group I'm in. - def set_mygroup - # retrieve the user name - group = %x{groups}.chomp.split(/ /)[0] - raise "Could not find group to set in @mygroup" unless group - @mygroup = group - end - - def fakefile(name) - ary = [basedir, "test"] - ary += name.split("/") - file = File.join(ary) - raise Puppet::DevError, "No fakedata file #{file}" unless FileTest.exists?(file) - file - end - - # wrap how to retrieve the masked mode - def filemode(file) - File.stat(file).mode & 007777 - end - - def memory - Puppet::Util.memory - end - - # a list of files that we can parse for testing - def textfiles - textdir = datadir "snippets" - Dir.entries(textdir).reject { |f| - f =~ /^\./ or f =~ /fail/ - }.each { |f| - yield File.join(textdir, f) - } - end - - def failers - textdir = datadir "failers" - # only parse this one file now - files = Dir.entries(textdir).reject { |file| - file =~ %r{\.swp} - }.reject { |file| - file =~ %r{\.disabled} - }.collect { |file| - File.join(textdir,file) - }.find_all { |file| - FileTest.file?(file) - }.sort.each { |file| - Puppet.debug "Processing #{file}" - yield file - } - end - - def mk_catalog(*resources) - if resources[0].is_a?(String) - name = resources.shift - else - name = :testing - end - config = Puppet::Resource::Catalog.new :testing do |conf| - resources.each { |resource| conf.add_resource resource } - end - - config - end -end diff --git a/test/lib/puppettest/testcase.rb b/test/lib/puppettest/testcase.rb deleted file mode 100755 index 0ec98846c..000000000 --- a/test/lib/puppettest/testcase.rb +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby -require 'puppettest' -require 'puppettest/runnable_test' -require 'test/unit' - -class PuppetTest::TestCase < Test::Unit::TestCase - include PuppetTest - extend PuppetTest::RunnableTest - - def self.suite - # Always skip this parent class. It'd be nice if there were a - # "supported" way to do this. - if self == PuppetTest::TestCase - suite = Test::Unit::TestSuite.new(name) - return suite - elsif self.runnable? - return super - else - puts "Skipping #{name}: #{@messages.join(", ")}" if defined? $console - suite = Test::Unit::TestSuite.new(name) - return suite - end - end -end diff --git a/test/lib/rake/puppet_test_loader.rb b/test/lib/rake/puppet_test_loader.rb deleted file mode 100644 index 17d29591f..000000000 --- a/test/lib/rake/puppet_test_loader.rb +++ /dev/null @@ -1,14 +0,0 @@ - -require 'test/unit/autorunner' -require 'getoptlong' -require 'puppettest' - -args = PuppetTest.munge_argv - -args.each { |f| require f unless f =~ /^-/ } - -runner = Test::Unit::AutoRunner.new(false) -runner.process_args - -exit 14 unless runner.run - diff --git a/test/lib/rake/puppet_testtask.rb b/test/lib/rake/puppet_testtask.rb deleted file mode 100644 index c490e5710..000000000 --- a/test/lib/rake/puppet_testtask.rb +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env ruby - -require 'rake' -require 'rake/testtask' - -module Rake - class PuppetTestTask < Rake::TestTask - def rake_loader - if Integer(RUBY_VERSION.split(/\./)[2]) < 4 - file = super - else - file = find_file('rake/puppet_test_loader') or - fail "unable to find rake test loader" - end - file - end - end -end - diff --git a/test/lib/stubba.rb b/test/lib/stubba.rb deleted file mode 100644 index 747054cfc..000000000 --- a/test/lib/stubba.rb +++ /dev/null @@ -1,2 +0,0 @@ -# for backwards compatibility -require 'mocha' diff --git a/test/network/authconfig.rb b/test/network/authconfig.rb deleted file mode 100755 index 3a4f18838..000000000 --- a/test/network/authconfig.rb +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' - -require 'puppet/network/authconfig' - -class TestAuthConfig < Test::Unit::TestCase - include PuppetTest - - def request(call, client, ip) - r = Puppet::Network::ClientRequest.new(client, ip, false) - h, m = call.split(".") - r.handler = h - r.method = m - r - end - - def test_parsingconfigfile - file = tempfile - assert(Puppet[:authconfig], "No config path") - - Puppet[:authconfig] = file - - File.open(file, "w") { |f| - f.puts "[pelementserver.describe] - allow *.madstop.com - deny 10.10.1.1 - -[fileserver] - allow *.madstop.com - deny 10.10.1.1 - -[fileserver.list] - allow 10.10.1.1 -" - } - - config = nil - assert_nothing_raised { - config = Puppet::Network::AuthConfig.new(file) - } - - assert_nothing_raised { - assert(config.allowed?(request("pelementserver.describe", "culain.madstop.com", "1.1.1.1")), "Did not allow host") - assert(! config.allowed?(request("pelementserver.describe", "culain.madstop.com", "10.10.1.1")), "Allowed host") - assert(config.allowed?(request("fileserver.yay", "culain.madstop.com", "10.1.1.1")), "Did not allow host to fs") - assert(! config.allowed?(request("fileserver.yay", "culain.madstop.com", "10.10.1.1")), "Allowed host to fs") - assert(config.allowed?(request("fileserver.list", "culain.madstop.com", "10.10.1.1")), "Did not allow host to fs.list") - } - end - - def test_singleton - auth = nil - assert_nothing_raised { auth = Puppet::Network::AuthConfig.main } - assert(auth, "did not get main authconfig") - - other = nil - assert_nothing_raised { other = Puppet::Network::AuthConfig.main } - - assert_equal( - auth.object_id, other.object_id, - - "did not get same authconfig from class") - end -end - - diff --git a/test/network/authorization.rb b/test/network/authorization.rb deleted file mode 100755 index 5a1254a84..000000000 --- a/test/network/authorization.rb +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'puppet/network/authorization' -require 'mocha' - -class TestAuthConfig < Test::Unit::TestCase - include PuppetTest - - # A mock class for authconfig - class FakeAuth - class << self - attr_accessor :allow, :exists - end - def allowed?(req) - self.class.allow - end - def exists? - self.class.exists - end - end - - class AuthTest - include Puppet::Network::Authorization - - def clear - @loaded.clear - end - - def load(name) - @loaded ||= [] - @loaded << name - end - - def handler_loaded?(name) - @loaded ||= [] - @loaded.include?(name) - end - end - - def setup - super - @obj = AuthTest.new - - # Override the authconfig to make life easier - class << @obj - def authconfig - @authconfig ||= FakeAuth.new - end - end - @request = Puppet::Network::ClientRequest.new("host", "ip", false) - @request.handler = "foo" - @request.method = "bar" - end - - def test_authconfig - obj = AuthTest.new - auth = nil - assert_nothing_raised { auth = obj.send(:authconfig) } - assert(auth, "did not get auth") - assert_equal(Puppet::Network::AuthConfig.main.object_id, auth.object_id, "did not get main authconfig") - end - - def test_authorize - # Make sure that unauthenticated clients can do puppetca stuff, but - # nothing else. - @request.handler = "puppetca" - @request.method = "yay" - assert(@obj.authorized?(@request), "Did not allow unauthenticated ca call") - assert_logged(:notice, /Allowing/, "did not log call") - @request.handler = "other" - assert(! @obj.authorized?(@request), "Allowed unauthencated other call") - assert_logged(:notice, /Denying/, "did not log call") - - @request.authenticated = true - # We start without the namespace auth file, so everything should - # start out denied - assert(! @obj.authorized?(@request), "Allowed call with no config file") - assert_logged(:notice, /Denying/, "did not log call") - - # Now set our run_mode to master, so calls are allowed - Puppet.run_mode.stubs(:master?).returns true - - assert( - @obj.authorized?(@request), - - "Denied call with no config file and master") - assert_logged(:debug, /Allowing/, "did not log call") - - # Now "create" the file, so we do real tests - FakeAuth.exists = true - - # We start out denying - assert(! @obj.authorized?(@request), "Allowed call when denying") - assert_logged(:notice, /Denying/, "did not log call") - - FakeAuth.allow = true - assert(@obj.authorized?(@request), "Denied call when allowing") - assert_logged(:debug, /Allowing/, "did not log call") - end - - def test_available? - # Start out false - assert(! @obj.available?(@request), "Defaulted to true") - assert_logged(:warning, /requested unavailable/, "did not log call") - - @obj.load(@request.handler) - assert(@obj.available?(@request), "did not see it loaded") - end - - # Make sure we raise things appropriately - def test_verify - # Start out unavailabl - assert_raise(Puppet::Network::InvalidClientRequest) do - @obj.verify(@request) - end - class << @obj - def available?(req) - true - end - end - assert_raise(Puppet::Network::InvalidClientRequest) do - @obj.verify(@request) - end - class << @obj - def authorized?(req) - true - end - end - assert_nothing_raised do - @obj.verify(@request) - end - end -end - - diff --git a/test/network/authstore.rb b/test/network/authstore.rb deleted file mode 100755 index e3c185302..000000000 --- a/test/network/authstore.rb +++ /dev/null @@ -1,540 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'mocha' -require 'puppet/network/authstore' - -class TestAuthStore < Test::Unit::TestCase - include PuppetTest - Declaration = Puppet::Network::AuthStore::Declaration - def mkstore - store = nil - assert_nothing_raised { - store = Puppet::Network::AuthStore.new - } - - store - end - - def setup - super - @store = mkstore - end - - def test_localallow - Puppet[:trace] = false - assert_nothing_raised { - assert(@store.allowed?(nil, nil), "Store disallowed local access") - } - - assert_raise(Puppet::DevError) { - @store.allowed?("kirby.madstop.com", nil) - } - - assert_raise(Puppet::DevError) { - @store.allowed?(nil, "192.168.0.1") - } - end - - def test_simpleips - %w{ - 192.168.0.5 - 7.0.48.7 - }.each { |ip| - assert_nothing_raised("Failed to @store IP address #{ip}") { - @store.allow(ip) - } - - assert(@store.allowed?("hosttest.com", ip), "IP #{ip} not allowed") - } - - #assert_raise(Puppet::AuthStoreError) { - # @store.allow("192.168.674.0") - #} - end - - def test_ipranges - %w{ - 192.168.0.* - 192.168.1.0/24 - 192.178.* - 193.179.0.0/8 - }.each { |range| - assert_nothing_raised("Failed to @store IP range #{range}") { - @store.allow(range) - } - } - - %w{ - 192.168.0.1 - 192.168.1.5 - 192.178.0.5 - 193.0.0.1 - }.each { |ip| - assert(@store.allowed?("fakename.com", ip), "IP #{ip} is not allowed") - } - end - - def test_iprangedenials - assert_nothing_raised("Failed to @store overlapping IP ranges") { - @store.allow("192.168.0.0/16") - @store.deny("192.168.0.0/24") - } - - assert(@store.allowed?("fake.name", "192.168.1.50"), "/16 ip not allowed") - assert(! @store.allowed?("fake.name", "192.168.0.50"), "/24 ip allowed") - end - - def test_subdomaindenails - assert_nothing_raised("Failed to @store overlapping IP ranges") { - @store.allow("*.madstop.com") - @store.deny("*.sub.madstop.com") - } - - - assert( - @store.allowed?("hostname.madstop.com", "192.168.1.50"), - - "hostname not allowed") - - assert( - ! @store.allowed?("name.sub.madstop.com", "192.168.0.50"), - - "subname name allowed") - end - - def test_orderingstuff - assert_nothing_raised("Failed to @store overlapping IP ranges") { - @store.allow("*.madstop.com") - @store.deny("192.168.0.0/24") - } - - - assert( - @store.allowed?("hostname.madstop.com", "192.168.1.50"), - - "hostname not allowed") - - assert( - ! @store.allowed?("hostname.madstop.com", "192.168.0.50"), - - "Host allowed over IP") - end - - def test_globalallow - assert_nothing_raised("Failed to add global allow") { - @store.allow("*") - } - - [ - %w{hostname.com 192.168.0.4}, - %w{localhost 192.168.0.1}, - %w{localhost 127.0.0.1} - - ].each { |ary| - assert(@store.allowed?(*ary), "Failed to allow #{ary.join(",")}") - } - end - - def test_store - assert_nothing_raised do - - assert_nil( - @store.send(:store, :allow, "*.host.com"), - - "store did not return nil") - end - assert_equal([Declaration.new(:allow, "*.host.com")], - @store.send(:instance_variable_get, "@declarations"), - "Did not store declaration") - - # Now add another one and make sure it gets sorted appropriately - assert_nothing_raised do - - assert_nil( - @store.send(:store, :allow, "me.host.com"), - - "store did not return nil") - end - - - assert_equal( - [ - Declaration.new(:allow, "me.host.com"), - - Declaration.new(:allow, "*.host.com") - ], - @store.send(:instance_variable_get, "@declarations"), - "Did not sort declarations") - end - - def test_allow_and_deny - store = Puppet::Network::AuthStore.new - store.expects(:store).with(:allow, "host.com") - store.allow("host.com") - - store = Puppet::Network::AuthStore.new - store.expects(:store).with(:deny, "host.com") - store.deny("host.com") - - store = Puppet::Network::AuthStore.new - assert_nothing_raised do - - assert_nil( - store.allow("*"), - - "allow did not return nil") - end - - - assert( - store.globalallow?, - - "did not enable global allow") - end - - def test_hostnames - Puppet[:trace] = false - %w{ - kirby.madstop.com - luke.madstop.net - name-other.madstop.net - }.each { |name| - assert_nothing_raised("Failed to @store simple name #{name}") { - @store.allow(name) - } - assert(@store.allowed?(name, "192.168.0.1"), "Name #{name} not allowed") - } - - %w{ - ^invalid! - inval$id - - }.each { |pat| - - assert_raise( - Puppet::AuthStoreError, - - "name '#{pat}' was allowed") { - @store.allow(pat) - } - } - end - - def test_domains - assert_nothing_raised("Failed to @store domains") { - @store.allow("*.a.very.long.domain.name.com") - @store.allow("*.madstop.com") - @store.allow("*.some-other.net") - @store.allow("*.much.longer.more-other.net") - } - - %w{ - madstop.com - culain.madstop.com - kirby.madstop.com - funtest.some-other.net - ya-test.madstop.com - some.much.much.longer.more-other.net - }.each { |name| - assert(@store.allowed?(name, "192.168.0.1"), "Host #{name} not allowed") - } - - assert_raise(Puppet::AuthStoreError) { - @store.allow("domain.*.com") - } - - - assert( - !@store.allowed?("very.long.domain.name.com", "1.2.3.4"), - - "Long hostname allowed") - - assert_raise(Puppet::AuthStoreError) { - @store.allow("domain.*.other.com") - } - end - - # #531 - def test_case_insensitivity - @store.allow("hostname.com") - - %w{hostname.com Hostname.COM hostname.Com HOSTNAME.COM}.each do |name| - assert(@store.allowed?(name, "127.0.0.1"), "did not allow #{name}") - end - end - - def test_allowed? - Puppet[:trace] = false - - assert( - @store.allowed?(nil, nil), - - "Did not default to true for local checks") - assert_raise(Puppet::DevError, "did not fail on one input") do - @store.allowed?("host.com", nil) - end - assert_raise(Puppet::DevError, "did not fail on one input") do - @store.allowed?(nil, "192.168.0.1") - end - - end - - # Make sure more specific allows and denies win over generalities - def test_specific_overrides - @store.allow("host.madstop.com") - @store.deny("*.madstop.com") - - - assert( - @store.allowed?("host.madstop.com", "192.168.0.1"), - - "More specific allowal by name failed") - - @store.allow("192.168.0.1") - @store.deny("192.168.0.0/24") - - - assert( - @store.allowed?("host.madstop.com", "192.168.0.1"), - - "More specific allowal by ip failed") - end - - def test_dynamic_backreferences - @store.allow("$1.madstop.com") - - assert_nothing_raised { @store.interpolate([nil, "host"]) } - assert(@store.allowed?("host.madstop.com", "192.168.0.1"), "interpolation failed") - assert_nothing_raised { @store.reset_interpolation } - end - - def test_dynamic_ip - @store.allow("192.168.0.$1") - - assert_nothing_raised { @store.interpolate([nil, "12"]) } - assert(@store.allowed?("host.madstop.com", "192.168.0.12"), "interpolation failed") - assert_nothing_raised { @store.reset_interpolation } - end - - def test_multiple_dynamic_backreferences - @store.allow("$1.$2") - - assert_nothing_raised { @store.interpolate([nil, "host", "madstop.com"]) } - assert(@store.allowed?("host.madstop.com", "192.168.0.1"), "interpolation failed") - assert_nothing_raised { @store.reset_interpolation } - end - - def test_multithreaded_allow_with_dynamic_backreferences - @store.allow("$1.madstop.com") - - threads = [] - 9.times { |a| - threads << Thread.new { - 9.times { |b| - Thread.pass - @store.interpolate([nil, "a#{b}", "madstop.com"]) - Thread.pass - assert( @store.allowed?("a#{b}.madstop.com", "192.168.0.1") ) - Thread.pass - @store.reset_interpolation - Thread.pass - } - } - } - threads.each { |th| th.join } - end - -end - -class TestAuthStoreDeclaration < PuppetTest::TestCase - include PuppetTest - Declaration = Puppet::Network::AuthStore::Declaration - - def setup - super - @decl = Declaration.new(:allow, "hostname.com") - end - - def test_parse - { - "192.168.0.1" => [:ip, IPAddr.new("192.168.0.1"), nil], - "2001:700:300:1800::" => [:ip, IPAddr.new("2001:700:300:1800::"), nil], - "2001:700:300:1800::/64" => [:ip, IPAddr.new("2001:700:300:1800::/64"), 64], - "192.168.0.1/32" => [:ip, IPAddr.new("192.168.0.1/32"), 32], - "192.168.0.1/24" => [:ip, IPAddr.new("192.168.0.1/24"), 24], - "192.*" => [:ip, IPAddr.new("192.0.0.0/8"), 8], - "192.168.*" => [:ip, IPAddr.new("192.168.0.0/16"), 16], - "192.168.0.*" => [:ip, IPAddr.new("192.168.0.0/24"), 24], - "hostname.com" => [:domain, %w{com hostname}, nil], - "Hostname.COM" => [:domain, %w{com hostname}, nil], - "billy.Hostname.COM" => [:domain, %w{com hostname billy}, nil], - "billy-jean.Hostname.COM" => [:domain, %w{com hostname billy-jean}, nil], - "*.hostname.COM" => [:domain, %w{com hostname}, 2], - "*.hostname.COM" => [:domain, %w{com hostname}, 2], - "$1.hostname.COM" => [:dynamic, %w{com hostname $1}, nil], - "192.168.$1.$2" => [:dynamic, %w{$2 $1 168 192}, nil], - "8A5BC90C-B8FD-4CBC-81DA-BAD84D551791" => [:opaque, %w{8A5BC90C-B8FD-4CBC-81DA-BAD84D551791}, nil] - }.each do |input, output| - - # Create a new decl each time, so values aren't cached. - assert_nothing_raised do - @decl = Declaration.new(:allow, input) - end - - [:name, :pattern, :length].zip(output).each do |method, value| - assert_equal(value, @decl.send(method), "Got incorrect value for #{method} from #{input}") - end - end - - %w{-hostname.com hostname.*}.each do |input| - assert_raise(Puppet::AuthStoreError, "Did not fail on #{input}") do - @decl.pattern = input - end - end - - ["hostname .com", "192.168 .0.1"].each do |input| - assert_raise(Puppet::AuthStoreError, "Did not fail on #{input}") do - @decl.pattern = input - end - end - end - - def test_result - ["allow", :allow].each do |val| - assert_nothing_raised { @decl.type = val } - assert_equal(true, @decl.result, "did not result to true with #{val.inspect}") - end - - [:deny, "deny"].each do |val| - assert_nothing_raised { @decl.type = val } - - assert_equal( - false, @decl.result, - - "did not result to false with #{val.inspect}") - end - - ["yay", 1, nil, false, true].each do |val| - assert_raise(ArgumentError, "Did not fail on #{val.inspect}") do - @decl.type = val - end - end - end - - def test_munge_name - { - "hostname.com" => %w{com hostname}, - "alley.hostname.com" => %w{com hostname alley}, - "*.hostname.com" => %w{com hostname *}, - "*.HOSTNAME.Com" => %w{com hostname *}, - "*.HOSTNAME.Com" => %w{com hostname *}, - - }.each do |input, output| - assert_equal(output, @decl.send(:munge_name, input), "munged #{input} incorrectly") - end - end - - # Make sure people can specify TLDs - def test_match_tlds - assert_nothing_raised { - @decl.pattern = "*.tld" - } - - assert_equal(%w{tld}, @decl.pattern, "Failed to allow custom tld") - end - - # Make sure we sort correctly. - def test_sorting - # Make sure declarations with no length sort first. - host_exact = Declaration.new(:allow, "host.com") - host_range = Declaration.new(:allow, "*.host.com") - - ip_exact = Declaration.new(:allow, "192.168.0.1") - ip_range = Declaration.new(:allow, "192.168.0.*") - - - assert_equal( - -1, host_exact <=> host_range, - - "exact name match did not sort first") - - - assert_equal( - -1, ip_exact <=> ip_range, - - "exact ip match did not sort first") - - # Next make sure we sort by length - ip_long = Declaration.new(:allow, "192.168.*") - assert_equal(-1, ip_range <=> ip_long, "/16 sorted before /24 in ip") - - # Now try it using masks - ip24 = Declaration.new(:allow, "192.168.0.0/24") - ip16 = Declaration.new(:allow, "192.168.0.0/16") - - assert_equal(-1, ip24 <=> ip16, "/16 sorted before /24 in ip with masks") - - # Make sure ip checks sort before host checks - assert_equal(-1, ip_exact <=> host_exact, "IP exact did not sort before host exact") - - - assert_equal( - -1, ip_range <=> host_range, - - "IP range did not sort before host range") - - host_long = Declaration.new(:allow, "*.domain.host.com") - - assert_equal(-1, host_long <=> host_range, "did not sort by domain length") - - # Now make sure denies sort before allows, for equivalent - # declarations. - host_deny = Declaration.new(:deny, "host.com") - assert_equal(-1, host_deny <=> host_exact, "deny did not sort before allow when exact") - - host_range_deny = Declaration.new(:deny, "*.host.com") - assert_equal(-1, host_range_deny <=> host_range, "deny did not sort before allow when ranged") - - ip_allow = Declaration.new(:allow, "192.168.0.0/16") - ip_deny = Declaration.new(:deny, "192.168.0.0/16") - - - assert_equal( - -1, ip_deny <=> ip_allow, - - "deny did not sort before allow in ip range") - - %w{host.com *.domain.com 192.168.0.1 192.168.0.1/24}.each do |decl| - assert_equal(0, Declaration.new(:allow, decl) <=> - Declaration.new(:allow, decl), - "Equivalent declarations for #{decl} were considered different" - ) - end - end - - def test_match? - host = Declaration.new(:allow, "host.com") - host.expects(:matchname?).with("host.com") - host.match?("host.com", "192.168.0.1") - - ip = Declaration.new(:allow, "192.168.0.1") - ip.pattern.expects(:include?) - ip.match?("host.com", "192.168.0.1") - end - - def test_matchname? - host = Declaration.new(:allow, "host.com") - assert(host.send(:matchname?, "host.com"), "exact did not match") - assert(! host.send(:matchname?, "yay.com"), "incorrect match") - - domain = Declaration.new(:allow, "*.domain.com") - %w{host.domain.com domain.com very.long.domain.com very-long.domain.com }.each do |name| - assert(domain.send(:matchname?, name), "Did not match #{name}") - end - end -end - - diff --git a/test/network/client_request.rb b/test/network/client_request.rb deleted file mode 100755 index 96b9d3e4f..000000000 --- a/test/network/client_request.rb +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' - -require 'puppet/network/client_request' - -class TestClientRequest < Test::Unit::TestCase - include PuppetTest - - def test_initialize - req = nil - assert_nothing_raised do - req = Puppet::Network::ClientRequest.new("name", "ip", false) - end - - assert_equal("name", req.name, "host name was not set correctly") - assert_equal("ip", req.ip, "host ip was not set correctly") - assert_equal(false, req.authenticated, "host auth was not set correctly") - assert(! req.authenticated, "host was incorrectly considered authenticated") - - req.authenticated = true - assert(req.authenticated, "host was not considered authenticated") - - assert_raise(ArgumentError) do - req.call - end - - req.handler = "yay" - req.method = "foo" - assert_equal("yay.foo", req.call, "call was not built correctly") - - assert_equal("name(ip)", req.to_s, "request string not correct") - end -end - - diff --git a/test/network/rights.rb b/test/network/rights.rb deleted file mode 100755 index 0167a98f1..000000000 --- a/test/network/rights.rb +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'puppet/network/rights' - -class TestRights < Test::Unit::TestCase - include PuppetTest - - def setup - super - @store = Puppet::Network::Rights.new - end - - - def test_rights - assert_raise(ArgumentError, "Did not fail on unknown right") { - @store.allowed?(:write, "host.madstop.com", "0.0.0.0") - } - - assert_nothing_raised { - @store.newright(:write) - } - - - assert( - ! @store.allowed?(:write, "host.madstop.com", "0.0.0.0"), - - "Defaulted to allowing access") - - assert_nothing_raised { - @store[:write].info "This is a log message" - } - - assert_logged(:info, /This is a log message/, "did not log from Rights") - end -end - - diff --git a/test/other/provider.rb b/test/other/provider.rb deleted file mode 100755 index c31c6bfb9..000000000 --- a/test/other/provider.rb +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/provider' -require 'puppettest' - -class TestImpl < Test::Unit::TestCase - include PuppetTest - - def setup - super - @type = newtype(@method_name.to_s + "type") - - # But create a new provider for every method. - @provider = newprovider(@method_name.to_s + "provider") - end - - def newtype(name) - # First create a fake type - return Puppet::Type.newtype(name) { - newparam(:name) { isnamevar } - } - end - - def newprovider(name, type = nil) - type ||= @type - provider = nil - assert_nothing_raised("Could not create provider") do - provider = type.provide(name) {} - end - provider - end - - def test_provider_default - nondef = nil - assert_nothing_raised { - nondef = newprovider(:nondefault) - } - - assert_nothing_raised do - @provider.defaultfor :operatingsystem => Facter["operatingsystem"].value - end - - assert_equal(@provider.name, @type.defaultprovider.name, "Did not get right provider") - - @type.suitableprovider - end - - def test_subclassconfines - parent = newprovider("parentprovider") - - # Now make a bad confine on the parent - parent.confine :exists => "/this/file/definitely/does/not/exist" - - child = nil - assert_nothing_raised { - child = @type.provide("child", :parent => parent.name) {} - } - - assert(child.suitable?, "Parent ruled out child") - end - - def test_commands - parent = newprovider("parentprovider") - - child = nil - assert_nothing_raised { - child = @type.provide("child", :parent => parent.name) {} - } - - assert_raise(Puppet::DevError) do - child.command(:nosuchcommand) - end - - # Now create a parent command - assert_nothing_raised { - parent.commands :sh => Puppet::Util.which('sh') - } - - assert(parent.command(:sh), "Did not find 'sh' command") - - assert(child.command(:sh), "Did not find parent's 'sh' command") - - assert(FileTest.exists?(child.command(:sh)), - "Somehow broke path to sh") - end -end - diff --git a/test/other/puppet.rb b/test/other/puppet.rb deleted file mode 100755 index 871860f08..000000000 --- a/test/other/puppet.rb +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppettest' - -# Test the different features of the main puppet module -class TestPuppetModule < Test::Unit::TestCase - include PuppetTest - - def mkfakeclient - Class.new(Puppet::Network::Client) do - def initialize - end - - def runnow - Puppet.info "fake client has run" - end - end - end - - def mktestclass - Class.new do - def initialize(file) - @file = file - end - - def started? - FileTest.exists?(@file) - end - - def start - File.open(@file, "w") do |f| f.puts "" end - end - - def shutdown - File.unlink(@file) - end - end - end - - def test_path - oldpath = ENV["PATH"] - cleanup do - ENV["PATH"] = oldpath - end - newpath = oldpath + ":/something/else" - assert_nothing_raised do - Puppet[:path] = newpath - end - - assert_equal(newpath, ENV["PATH"]) - end - - def test_libdir - oldlibs = $LOAD_PATH.dup - cleanup do - $LOAD_PATH.each do |dir| - $LOAD_PATH.delete(dir) unless oldlibs.include?(dir) - end - end - one = tempfile - two = tempfile - Dir.mkdir(one) - Dir.mkdir(two) - - # Make sure setting the libdir gets the dir added to $LOAD_PATH - assert_nothing_raised do - Puppet[:libdir] = one - end - - assert($LOAD_PATH.include?(one), "libdir was not added") - - # Now change it, make sure it gets added and the old one gets - # removed - assert_nothing_raised do - Puppet[:libdir] = two - end - - assert($LOAD_PATH.include?(two), "libdir was not added") - assert(! $LOAD_PATH.include?(one), "old libdir was not removed") - end -end - diff --git a/test/other/relationships.rb b/test/other/relationships.rb deleted file mode 100755 index e36dcda71..000000000 --- a/test/other/relationships.rb +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppettest' - -class TestRelationships < Test::Unit::TestCase - include PuppetTest - def setup - super - Puppet::Type.type(:exec) - end - - def newfile - assert_nothing_raised { - return Puppet::Type.type(:file).new( - :path => tempfile, - :check => [:mode, :owner, :group] - ) - } - end - - def check_relationship(sources, targets, out, refresher) - if out - deps = sources.builddepends - sources = [sources] - else - deps = targets.builddepends - targets = [targets] - end - assert_instance_of(Array, deps) - assert(! deps.empty?, "Did not receive any relationships") - - deps.each do |edge| - assert_instance_of(Puppet::Relationship, edge) - end - - sources.each do |source| - targets.each do |target| - edge = deps.find { |e| e.source == source and e.target == target } - assert(edge, "Could not find edge for #{source.ref} => #{target.ref}") - - if refresher - assert_equal(:ALL_EVENTS, edge.event) - assert_equal(:refresh, edge.callback) - else - assert_nil(edge.event) - assert_nil(edge.callback, "Got a callback with no events") - end - end - end - end - - def test_autorequire - # We know that execs autorequire their cwd, so we'll use that - path = tempfile - file = Puppet::Type.type(:file).new( - :title => "myfile", :path => path, - :ensure => :directory - ) - exec = Puppet::Type.newexec( - :title => "myexec", :cwd => path, - :command => "/bin/echo" - ) - catalog = mk_catalog(file, exec) - reqs = nil - assert_nothing_raised do - reqs = exec.autorequire - end - assert_instance_of(Puppet::Relationship, reqs[0], "Did not return a relationship edge") - assert_equal(file, reqs[0].source, "Did not set the autorequire source correctly") - assert_equal(exec, reqs[0].target, "Did not set the autorequire target correctly") - - # Now make sure that these relationships are added to the - # relationship graph - catalog.apply do |trans| - assert(catalog.relationship_graph.path_between(file, exec), "autorequire edge was not created") - end - end - - # Testing #411. It was a problem with builddepends. - def test_missing_deps - file = Puppet::Type.type(:file).new :path => tempfile, :require => Puppet::Resource.new("file", "/no/such/file") - - assert_raise(Puppet::Error) do - file.builddepends - end - end -end - diff --git a/test/other/report.rb b/test/other/report.rb deleted file mode 100755 index fb206470a..000000000 --- a/test/other/report.rb +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/reports' -require 'puppet/transaction/report' -require 'puppettest' -require 'puppettest/reporttesting' - -class TestReports < Test::Unit::TestCase - include PuppetTest - include PuppetTest::Reporttesting - - def mkreport - # First do some work - objects = [] - 6.times do |i| - file = tempfile - - # Make every third file - File.open(file, "w") { |f| f.puts "" } if i % 3 == 0 - - - objects << Puppet::Type.type(:file).new( - - :path => file, - - :ensure => "file" - ) - end - - config = mk_catalog(*objects) - # So the report works out. - config.retrieval_duration = 0.001 - trans = config.apply - - trans.generate_report - end - - # Make sure we can use reports as log destinations. - def test_reports_as_log_destinations - report = fakereport - - assert_nothing_raised { - Puppet::Util::Log.newdestination(report) - } - - # Now make a file for testing logging - file = Puppet::Type.type(:file).new(:path => tempfile, :ensure => "file") - file.finish - - log = nil - assert_nothing_raised { - log = file.log "This is a message, yo" - } - - assert(report.logs.include?(log), "Report did not get log message") - - assert_nothing_raised { - Puppet::Util::Log.close(report) - } - - log = file.log "This is another message, yo" - - assert(! report.logs.include?(log), "Report got log message after close") - end - - def test_store_report - # Create a bunch of log messages in an array. - report = Puppet::Transaction::Report.new("apply") - - # We have to reuse reporting here because of something going on in the - # server/report.rb file - Puppet.settings.use(:main, :master) - - 3.times { |i| - log = Puppet.warning("Report test message #{i}") - - report << log - } - - assert_nothing_raised do - report.extend(Puppet::Reports.report(:store)) - end - - yaml = YAML.dump(report) - - file = report.process - - assert(FileTest.exists?(file), "report file did not get created") - assert_equal(yaml, File.read(file), "File did not get written") - end - - if Puppet.features.rrd? || Puppet.features.rrd_legacy? - def test_rrdgraph_report - Puppet.settings.use(:main, :metrics) - report = mkreport - - assert(! report.metrics.empty?, "Did not receive any metrics") - - assert_nothing_raised do - report.extend(Puppet::Reports.report(:rrdgraph)) - end - - assert_nothing_raised { - report.process - } - - hostdir = nil - assert_nothing_raised do - hostdir = report.hostdir - end - - assert(hostdir, "Did not get hostdir back") - - assert(FileTest.directory?(hostdir), "Host rrd dir did not get created") - index = File.join(hostdir, "index.html") - assert(FileTest.exists?(index), "index file was not created") - - # Now make sure it creaets each of the rrd files - %w{changes resources time}.each do |type| - file = File.join(hostdir, "#{type}.rrd") - assert(FileTest.exists?(file), "Did not create rrd file for #{type}") - - daily = file.sub ".rrd", "-daily.png" - assert(FileTest.exists?(daily), "Did not make daily graph for #{type}") - end - - end - else - $stderr.puts "Install RRD for metric reporting tests" - end -end - diff --git a/test/other/transactions.rb b/test/other/transactions.rb deleted file mode 100755 index d77fd1538..000000000 --- a/test/other/transactions.rb +++ /dev/null @@ -1,395 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'mocha' -require 'puppet' -require 'puppettest' -require 'puppettest/support/resources' -require 'puppettest/support/utils' - -class TestTransactions < Test::Unit::TestCase - include PuppetTest::FileTesting - include PuppetTest::Support::Resources - include PuppetTest::Support::Utils - class Fakeprop true) - def finish - $finished << self.name - end - end - type.class_eval(&block) if block - cleanup do - Puppet::Type.rmtype(:generator) - end - - type - end - - # Create a new type that generates instances with shorter names. - def mkreducer(&block) - type = mkgenerator do - def eval_generate - ret = [] - if title.length > 1 - ret << self.class.new(:title => title[0..-2]) - else - return nil - end - ret - end - end - - type.class_eval(&block) if block - - type - end - - def test_prefetch - # Create a type just for testing prefetch - name = :prefetchtesting - $prefetched = false - type = Puppet::Type.newtype(name) do - newparam(:name) {} - end - - cleanup do - Puppet::Type.rmtype(name) - end - - # Now create a provider - type.provide(:prefetch) do - def self.prefetch(resources) - $prefetched = resources - end - end - - # Now create an instance - inst = type.new :name => "yay" - - # Create a transaction - trans = Puppet::Transaction.new(mk_catalog(inst)) - - # Make sure it gets called from within evaluate - $prefetched = false - assert_nothing_raised do - trans.evaluate - end - - assert_equal({inst.title => inst}, $prefetched, "evaluate did not call prefetch") - end - - def test_ignore_tags? - config = Puppet::Resource::Catalog.new - config.host_config = true - transaction = Puppet::Transaction.new(config) - assert(! transaction.ignore_tags?, "Ignoring tags when applying a host catalog") - - config.host_config = false - transaction = Puppet::Transaction.new(config) - assert(transaction.ignore_tags?, "Not ignoring tags when applying a non-host catalog") - end - - def test_missing_tags? - resource = Puppet::Type.type(:notify).new :title => "foo" - resource.stubs(:tagged?).returns true - config = Puppet::Resource::Catalog.new - - # Mark it as a host config so we don't care which test is first - config.host_config = true - transaction = Puppet::Transaction.new(config) - assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when none are set") - - # host catalogs pay attention to tags, no one else does. - Puppet[:tags] = "three,four" - config.host_config = false - transaction = Puppet::Transaction.new(config) - assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when not running a host catalog") - - # - config.host_config = true - transaction = Puppet::Transaction.new(config) - assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when running a host catalog and all tags are present") - - transaction = Puppet::Transaction.new(config) - resource.stubs :tagged? => false - assert(transaction.missing_tags?(resource), "Considered a resource not to be missing tags when running a host catalog and tags are missing") - end - - # Make sure changes in contained files still generate callback events. - def test_generated_callbacks - dir = tempfile - maker = tempfile - Dir.mkdir(dir) - file = File.join(dir, "file") - File.open(file, "w") { |f| f.puts "" } - File.chmod(0644, file) - File.chmod(0755, dir) # So only the child file causes a change - - dirobj = Puppet::Type.type(:file).new :mode => "755", :recurse => true, :path => dir - exec = Puppet::Type.type(:exec).new :title => "make", - :command => "touch #{maker}", :path => ENV['PATH'], :refreshonly => true, - :subscribe => dirobj - - assert_apply(dirobj, exec) - assert(FileTest.exists?(maker), "Did not make callback file") - end - - # Testing #401 -- transactions are calling refresh on classes that don't support it. - def test_callback_availability - $called = [] - klass = Puppet::Type.newtype(:norefresh) do - newparam(:name, :namevar => true) {} - def method_missing(method, *args) - $called << method - end - end - cleanup do - $called = nil - Puppet::Type.rmtype(:norefresh) - end - - file = Puppet::Type.type(:file).new :path => tempfile, :content => "yay" - one = klass.new :name => "one", :subscribe => file - - assert_apply(file, one) - - assert(! $called.include?(:refresh), "Called refresh when it wasn't set as a method") - end - - # Testing #437 - cyclic graphs should throw failures. - def test_fail_on_cycle - one = Puppet::Type.type(:exec).new(:name => "/bin/echo one") - two = Puppet::Type.type(:exec).new(:name => "/bin/echo two") - one[:require] = two - two[:require] = one - - config = mk_catalog(one, two) - trans = Puppet::Transaction.new(config) - assert_raise(Puppet::Error) do - trans.evaluate - end - end - - def test_errors_during_generation - type = Puppet::Type.newtype(:failer) do - newparam(:name) {} - def eval_generate - raise ArgumentError, "Invalid value" - end - def generate - raise ArgumentError, "Invalid value" - end - end - cleanup { Puppet::Type.rmtype(:failer) } - - obj = type.new(:name => "testing") - - assert_apply(obj) - end - - def test_self_refresh_causes_triggering - type = Puppet::Type.newtype(:refresher, :self_refresh => true) do - attr_accessor :refreshed, :testing - newparam(:name) {} - newproperty(:testing) do - def retrieve - :eh - end - - def sync - # noop - :ran_testing - end - end - def refresh - @refreshed = true - end - end - cleanup { Puppet::Type.rmtype(:refresher)} - - obj = type.new(:name => "yay", :testing => "cool") - - assert(! obj.insync?(obj.retrieve), "fake object is already in sync") - - # Now make sure it gets refreshed when the change happens - assert_apply(obj) - assert(obj.refreshed, "object was not refreshed during transaction") - end - - # Testing #433 - def test_explicit_dependencies_beat_automatic - # Create a couple of different resource sets that have automatic relationships and make sure the manual relationships win - rels = {} - # Now add the explicit relationship - # Now files - d = tempfile - f = File.join(d, "file") - file = Puppet::Type.type(:file).new(:path => f, :content => "yay") - dir = Puppet::Type.type(:file).new(:path => d, :ensure => :directory, :require => file) - - rels[dir] = file - rels.each do |after, before| - config = mk_catalog(before, after) - trans = Puppet::Transaction.new(config) - str = "from #{before} to #{after}" - - assert_nothing_raised("Failed to create graph #{str}") do - trans.add_dynamically_generated_resources - end - - - graph = trans.relationship_graph - assert(graph.edge?(before, after), "did not create manual relationship #{str}") - assert(! graph.edge?(after, before), "created automatic relationship #{str}") - end - end - - # #542 - make sure resources in noop mode still notify their resources, - # so that users know if a service will get restarted. - def test_noop_with_notify - path = tempfile - epath = tempfile - spath = tempfile - - file = Puppet::Type.type(:file).new( - :path => path, :ensure => :file, - - :title => "file") - - exec = Puppet::Type.type(:exec).new( - :command => "touch #{epath}", - :path => ENV["PATH"], :subscribe => file, :refreshonly => true, - - :title => 'exec1') - - exec2 = Puppet::Type.type(:exec).new( - :command => "touch #{spath}", - :path => ENV["PATH"], :subscribe => exec, :refreshonly => true, - - :title => 'exec2') - - Puppet[:noop] = true - - assert(file.noop, "file not in noop") - assert(exec.noop, "exec not in noop") - - @logs.clear - assert_apply(file, exec, exec2) - - assert(! FileTest.exists?(path), "Created file in noop") - assert(! FileTest.exists?(epath), "Executed exec in noop") - assert(! FileTest.exists?(spath), "Executed second exec in noop") - - assert(@logs.detect { |l| - l.message =~ /should be/ and l.source == file.property(:ensure).path}, - "did not log file change") - - assert( - @logs.detect { |l| - l.message =~ /Would have/ and l.source == exec.path }, - - "did not log first exec trigger") - - assert( - @logs.detect { |l| - l.message =~ /Would have/ and l.source == exec2.path }, - - "did not log second exec trigger") - end - - def test_only_stop_purging_with_relations - files = [] - paths = [] - 3.times do |i| - path = tempfile - paths << path - - file = Puppet::Type.type(:file).new( - :path => path, :ensure => :absent, - - :backup => false, :title => "file#{i}") - File.open(path, "w") { |f| f.puts "" } - files << file - end - - files[0][:ensure] = :file - files[0][:require] = files[1..2] - - # Mark the second as purging - files[1].purging - - assert_apply(*files) - - assert(FileTest.exists?(paths[1]), "Deleted required purging file") - assert(! FileTest.exists?(paths[2]), "Did not delete non-purged file") - end - - def test_flush - $state = :absent - $flushed = 0 - type = Puppet::Type.newtype(:flushtest) do - newparam(:name) - newproperty(:ensure) do - newvalues :absent, :present, :other - def retrieve - $state - end - def set(value) - $state = value - :thing_changed - end - end - - def flush - $flushed += 1 - end - end - - cleanup { Puppet::Type.rmtype(:flushtest) } - - obj = type.new(:name => "test", :ensure => :present) - - # first make sure it runs through and flushes - assert_apply(obj) - - assert_equal(:present, $state, "Object did not make a change") - assert_equal(1, $flushed, "object was not flushed") - - # Now run a noop and make sure we don't flush - obj[:ensure] = "other" - obj[:noop] = true - - assert_apply(obj) - assert_equal(:present, $state, "Object made a change in noop") - assert_equal(1, $flushed, "object was flushed in noop") - end -end diff --git a/test/puppet/defaults.rb b/test/puppet/defaults.rb deleted file mode 100755 index 7b7f6dbe3..000000000 --- a/test/puppet/defaults.rb +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppettest' - - -class TestPuppetDefaults < Test::Unit::TestCase - include PuppetTest - @@dirs = %w{rrddir confdir vardir logdir statedir} - @@files = %w{statefile manifest masterlog} - @@normals = %w{puppetport masterport server} - @@booleans = %w{noop} - - def testVersion - assert( Puppet.version =~ /^[0-9]+(\.[0-9]+)*/, "got invalid version number #{Puppet.version}") - end - - def testStringOrParam - [@@dirs,@@files,@@booleans].flatten.each { |param| - assert_nothing_raised { Puppet[param] } - assert_nothing_raised { Puppet[param.intern] } - } - end - - def test_valuesForEach - [@@dirs,@@files,@@booleans].flatten.each { |param| - param = param.intern - assert_nothing_raised { Puppet[param] } - } - end - - def testValuesForEach - [@@dirs,@@files,@@booleans].flatten.each { |param| - assert_nothing_raised { Puppet[param] } - } - end - - # we don't want user defaults in /, or root defaults in ~ - def testDefaultsInCorrectRoots - notval = nil - if Puppet.features.root? - notval = Regexp.new(File.expand_path("~")) - else - notval = /^\/var|^\/etc/ - end - [@@dirs,@@files].flatten.each { |param| - value = Puppet[param] - - assert_nothing_raised { raise "#{param} is incorrectly set to #{value}" } unless value !~ notval - } - end - - def test_settingdefaults - testvals = { - :fakeparam => "$confdir/yaytest", - :anotherparam => "$vardir/goodtest", - :string => "a yay string", - :boolean => true - } - - testvals.each { |param, default| - assert_nothing_raised { - Puppet.define_settings("testing", param => [default, "a value"]) - } - } - end -end diff --git a/test/puppet/errortest.rb b/test/puppet/errortest.rb deleted file mode 100755 index 35f2ed39e..000000000 --- a/test/puppet/errortest.rb +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppettest' - -class TestError < Test::Unit::TestCase - include PuppetTest - - def test_errorisstring - error = nil - assert_nothing_raised { - error = Puppet::ParseError.new("This is an error") - } - assert_instance_of(String, error.to_s) - end -end - diff --git a/test/rails/rails.rb b/test/rails/rails.rb deleted file mode 100755 index a9a750ffd..000000000 --- a/test/rails/rails.rb +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/rails' -require 'puppet/parser/parser' -require 'puppettest' -require 'puppettest/parsertesting' -require 'puppettest/resourcetesting' -require 'puppettest/railstesting' - -class TestRails < Test::Unit::TestCase - include PuppetTest::ParserTesting - include PuppetTest::ResourceTesting - include PuppetTest::RailsTesting - - def test_includerails - assert_nothing_raised { - require 'puppet/rails' - } - end -end - diff --git a/test/rails/railsparameter.rb b/test/rails/railsparameter.rb deleted file mode 100755 index fafa2b7e7..000000000 --- a/test/rails/railsparameter.rb +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/rails' -require 'puppettest' -require 'puppettest/railstesting' - -# Don't do any tests w/out this class -if defined? ::ActiveRecord::Base -class TestRailsParameter < Test::Unit::TestCase - include PuppetTest::RailsTesting - - def params - {"myname" => "myval", "multiple" => %w{one two three}} - end - - # Create a resource param from a rails parameter - def test_to_resourceparam - railsinit - - # Now create a source - parser = mkparser - source = parser.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "myclass") - - host = Puppet::Rails::Host.new(:name => "myhost") - - host.save - - - resource = host.resources.create( - - :title => "/tmp/to_resource", - :restype => "file", - - :exported => true) - - # Use array and non-array values, to make sure we get things back in - # the same form. - params.each do |name, value| - param = Puppet::Rails::ParamName.find_or_create_by_name(name) - if value.is_a? Array - values = value - else - values = [value] - end - valueobjects = values.collect do |v| - - resource.param_values.create( - :value => v, - - :param_name => param) - end - - assert(param, "Did not create rails parameter") - - # The id doesn't get assigned until we save - end - - resource.save - - # And try to convert our parameter - params.each do |name, value| - param = Puppet::Rails::ParamName.find_by_name(name) - pp = nil - assert_nothing_raised do - pp = param.to_resourceparam(resource, source) - end - - assert_instance_of(Puppet::Parser::Resource::Param, pp) - assert_equal(name.to_sym, pp.name, "parameter name was not equal") - assert_equal(value, pp.value, "value was not equal for #{value.inspect}") - end - end -end -else - $stderr.puts "Install Rails for Rails and Caching tests" -end - diff --git a/test/ral/manager/attributes.rb b/test/ral/manager/attributes.rb deleted file mode 100755 index c3e449e9e..000000000 --- a/test/ral/manager/attributes.rb +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env ruby -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'mocha' - -class TestTypeAttributes < Test::Unit::TestCase - include PuppetTest - - def mktype - type = Puppet::Type.newtype(:faketype) {} - cleanup { Puppet::Type.rmtype(:faketype) } - type - end - - def test_bracket_methods - type = mktype - - # make a namevar - type.newparam(:name) {} - - # make a property - type.newproperty(:property) {} - - # and a param - type.newparam(:param) - - inst = type.new(:name => "yay") - - # Make sure we can set each of them, including a metaparam - [:param, :property, :noop].each do |param| - assert_nothing_raised("Failed to set symbol") do - inst[param] = true - end - - assert_nothing_raised("Failed to set string") do - inst[param.to_s] = true - end - - if param == :property - assert(inst.property(param), "did not get obj for #{param}") - - assert_equal( - true, inst.should(param), - - "should value did not get set") - else - assert_equal(true, inst[param], "did not get correct value for #{param} from symbol") - assert_equal(true, inst[param.to_s], "did not get correct value for #{param} from string") - end - end - end - - def test_properties - type = mktype - - # make a namevar - type.newparam(:name) {} - - # make a couple of properties - props = [:one, :two, :three] - props.each do |prop| - type.newproperty(prop) {} - end - - inst = type.new(:name => "yay") - - inst[:one] = "boo" - one = inst.property(:one) - assert(one, "did not get obj for one") - assert_equal([one], inst.send(:properties), "got wrong properties") - - inst[:three] = "rah" - three = inst.property(:three) - assert(three, "did not get obj for three") - assert_equal([one, three], inst.send(:properties), "got wrong properties") - - inst[:two] = "whee" - two = inst.property(:two) - assert(two, "did not get obj for two") - assert_equal([one, two, three], inst.send(:properties), "got wrong properties") - end - - def attr_check(type) - @num ||= 0 - @num += 1 - name = "name#{@num}" - inst = type.new(:name => name) - [:meta, :param, :prop].each do |name| - klass = type.attrclass(name) - assert(klass, "did not get class for #{name}") - obj = yield inst, klass - assert_instance_of(klass, obj, "did not get object back") - - assert_equal( - "value", inst.value(klass.name), - - "value was not correct from value method") - assert_equal("value", obj.value, "value was not correct") - end - end - - def test_newattr - type = mktype - type.newparam(:name) {} - - # Make one of each param type - { - :meta => :newmetaparam, :param => :newparam, :prop => :newproperty - }.each do |name, method| - assert_nothing_raised("Could not make #{name} of type #{method}") do - type.send(method, name) {} - end - end - - # Now set each of them - attr_check(type) do |inst, klass| - property = inst.newattr(klass.name) - property.value = "value" - property - end - - # Now try it passing the class in - attr_check(type) do |inst, klass| - property = inst.newattr(klass) - property.value = "value" - property - end - - # Lastly, make sure we can create and then set, separately - attr_check(type) do |inst, klass| - obj = inst.newattr(klass.name) - assert_nothing_raised("Could not set value after creation") do - obj.value = "value" - end - - # Make sure we can't create a new param object - new_attr = inst.newattr(klass.name) - assert_equal(new_attr, obj, "newattr should return the same object if called a second time") - - obj - end - end - - def test_alias_parameter - type = mktype - type.newparam(:name) {} - type.newparam(:one) {} - type.newproperty(:two) {} - - aliases = { - :three => :one, - :four => :two - } - aliases.each do |new, old| - assert_nothing_raised("Could not create alias parameter #{new}") do - type.set_attr_alias new => old - end - end - - aliases.each do |new, old| - assert_equal(old, type.attr_alias(new), "did not return alias info for #{new}") - end - - assert_nil(type.attr_alias(:name), "got invalid alias info for name") - - inst = type.new(:name => "my name") - assert(inst, "could not create instance") - - aliases.each do |new, old| - val = "value #{new}" - assert_nothing_raised do - inst[new] = val - end - - case old - when :one # param - - assert_equal( - val, inst[new], - - "Incorrect alias value for #{new} in []") - else - assert_equal(val, inst.should(new), "Incorrect alias value for #{new} in should") - end - assert_equal(val, inst.value(new), "Incorrect alias value for #{new}") - assert_equal(val, inst.value(old), "Incorrect orig value for #{old}") - end - end - - # Make sure newattr handles required features correctly. - def test_newattr_and_required_features - # Make a type with some features - type = mktype - type.feature :fone, "Something" - type.feature :ftwo, "Something else" - type.newparam(:name) {} - - # Make three properties: one with no requirements, one with one, and one with two - none = type.newproperty(:none) {} - one = type.newproperty(:one, :required_features => :fone) {} - two = type.newproperty(:two, :required_features => [:fone, :ftwo]) {} - - # Now make similar providers - nope = type.provide(:nope) {} - maybe = type.provide(:maybe) { has_feature :fone} - yep = type.provide(:yep) { has_features :fone, :ftwo} - - attrs = [:none, :one, :two] - - # Now make sure that we get warnings and no properties in those cases where our providers do not support the features requested - [nope, maybe, yep].each_with_index do |prov, i| - resource = type.new(:provider => prov.name, :name => "test#{i}", :none => "a", :one => "b", :two => "c") - - case prov.name - when :nope - yes = [:none] - no = [:one, :two] - when :maybe - yes = [:none, :one] - no = [:two] - when :yep - yes = [:none, :one, :two] - no = [] - end - yes.each { |a| assert(resource.should(a), "Did not get value for #{a} in #{prov.name}") } - no.each do |a| - assert_nil(resource.should(a), "Got value for unsupported %s in %s" % [a, prov.name]) - if Puppet::Util::Log.sendlevel?(:info) - assert(@logs.find { |l| l.message =~ /not managing attribute #{a}/ and l.level == :debug }, "No warning about failed %s" % a) - end - end - - @logs.clear - end - end - - # Make sure the 'check' metaparam just ignores non-properties, rather than failing. - def test_check_allows_parameters - file = Puppet::Type.type(:file) - klass = file.attrclass(:check) - - resource = file.new(:path => tempfile) - inst = klass.new(:resource => resource) - - {:property => [:owner, :group], :parameter => [:ignore, :recurse], :metaparam => [:require, :subscribe]}.each do |attrtype, attrs| - assert_nothing_raised("Could not set check to a single #{attrtype} value") do - inst.value = attrs[0] - end - - if attrtype == :property - assert(resource.property(attrs[0]), "Check did not create property instance during single check") - end - assert_nothing_raised("Could not set check to multiple #{attrtype} values") do - inst.value = attrs - end - if attrtype == :property - assert(resource.property(attrs[1]), "Check did not create property instance during multiple check") - end - end - - # But make sure actually invalid attributes fail - assert_raise(Puppet::Error, ":check did not fail on invalid attribute") do - inst.value = :nosuchattr - end - end - - def test_check_ignores_unsupported_params - type = Puppet::Type.newtype(:unsupported) do - feature :nosuchfeat, "testing" - newparam(:name) {} - newproperty(:yep) {} - newproperty(:nope, :required_features => :nosuchfeat) {} - end - $yep = :absent - type.provide(:only) do - def self.supports_parameter?(param) - param.name != :nope - end - - def yep - $yep - end - def yep=(v) - $yep = v - end - end - cleanup { Puppet::Type.rmtype(:unsupported) } - - obj = type.new(:name => "test", :check => :yep) - obj.stubs(:newattr).returns(stub_everything("newattr")) - obj.expects(:newattr).with(:nope).never - obj[:check] = :all - end -end - diff --git a/test/ral/manager/instances.rb b/test/ral/manager/instances.rb deleted file mode 100755 index f59f43da1..000000000 --- a/test/ral/manager/instances.rb +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env ruby -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' - -class TestTypeInstances < Test::Unit::TestCase - include PuppetTest - - def setup - super - @type = Puppet::Type.newtype(:instance_test) do - newparam(:name) {} - ensurable - end - cleanup { Puppet::Type.rmtype(:instance_test) } - end - - # Make sure the instances class method works as expected. - def test_instances - # First make sure it throws an error when there are no providers - assert_raise(Puppet::DevError, "Did not fail when no providers are present") do - @type.instances - end - - # Now add a couple of providers - - # The default - @type.provide(:default) do - defaultfor :operatingsystem => Facter.value(:operatingsystem) - mk_resource_methods - class << self - attr_accessor :names - end - def self.instance(name) - new(:name => name, :ensure => :present) - end - def self.instances - @instances ||= names.collect { |name| instance(name) } - end - - @names = [:one, :five, :six] - end - - # A provider with the same source - @type.provide(:sub, :source => :default, :parent => :default) do - @names = [:two, :seven, :eight] - end - - # An unsuitable provider - @type.provide(:nope, :parent => :default) do - confine :exists => "/no/such/file" - @names = [:three, :nine, :ten] - end - - # Another suitable, non-default provider - @type.provide(:yep, :parent => :default) do - @names = [:four, :seven, :ten] - end - - # Now make a couple of instances, so we know we correctly match instead of always - # trying to create new ones. - one = @type.new(:name => :one, :ensure => :present) - three = @type.new(:name => :three, :ensure => :present, :provider => :sub) - five = @type.new(:name => :five, :ensure => :present, :provider => :yep) - - result = nil - assert_nothing_raised("Could not get instance list") do - result = @type.instances - end - - result.each do |resource| - assert_instance_of(@type, resource, "Returned non-resource") - end - - assert_equal(:one, result[0].name, "Did not get default instances first") - - resources = result.inject({}) { |hash, res| hash[res.name] = res; hash } - assert(resources.include?(:four), "Did not get resources from other suitable providers") - assert(! resources.include?(:three), "Got resources from unsuitable providers") - - # Now make sure we didn't change the provider type for :five - assert_equal(:yep, five.provider.class.name, "Changed provider type when listing resources") - - # Now make sure the resources have an 'ensure' property to go with the value in the provider - assert(resources[:one].send(:instance_variable_get, "@parameters").include?(:ensure), "Did not create ensure property") - end -end - diff --git a/test/ral/manager/manager.rb b/test/ral/manager/manager.rb deleted file mode 100755 index e42c6c293..000000000 --- a/test/ral/manager/manager.rb +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env ruby -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' - -class TestTypeManager < Test::Unit::TestCase - include PuppetTest - - class FakeManager - extend Puppet::MetaType::Manager - def self.clear - @types = {} - end - end - - def teardown - super - FakeManager.clear - end - - # Make sure we can remove defined types - def test_rmtype - assert_nothing_raised { - FakeManager.newtype :testing do - newparam(:name, :namevar => true) - end - } - assert(FakeManager.type(:testing), "Did not get fake type") - - assert_nothing_raised do - FakeManager.rmtype(:testing) - end - - assert_nil(FakeManager.type(:testing), "Type was not removed") - assert(! defined?(FakeManager::Testing), "Constant was not removed") - end - - def test_newtype - assert_nothing_raised do - FakeManager.newtype(:testing, :self_refresh => true) do - newparam(:name, :namevar => true) - end - end - - test = FakeManager.type(:testing) - assert(test, "did not get type") - assert(test.self_refresh, "did not set attribute") - end -end - diff --git a/test/ral/manager/provider.rb b/test/ral/manager/provider.rb deleted file mode 100755 index 1d7265b7c..000000000 --- a/test/ral/manager/provider.rb +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'mocha' - -class TestTypeProviders < Test::Unit::TestCase - include PuppetTest - - def setup - super - @type = Puppet::Type.newtype(:provider_test) do - newparam(:name) {} - ensurable - end - cleanup { Puppet::Type.rmtype(:provider_test) } - end - - # Make sure default providers behave correctly - def test_defaultproviders - basic = @type.provide(:basic) do - defaultfor :operatingsystem => :somethingelse, - :operatingsystemrelease => :yayness - end - - assert_equal(basic, @type.defaultprovider) - @type.defaultprovider = nil - - greater = @type.provide(:greater) do - defaultfor :operatingsystem => Facter.value("operatingsystem") - end - - assert_equal(greater, @type.defaultprovider) - end - - # Make sure the provider is always the first parameter created. - def test_provider_sorting - should = [:name, :ensure] - assert_equal(should, @type.allattrs.reject { |p| ! should.include?(p) }, "Got wrong order of parameters") - - @type.provide(:yay) { } - should = [:name, :provider, :ensure] - assert_equal(should, @type.allattrs.reject { |p| ! should.include?(p) }, - "Providify did not reorder parameters") - end - - # Make sure that provider instances can be passed in directly. - def test_name_or_provider - provider = @type.provide(:testing) do - end - - # first make sure we can pass the name in - resource = nil - assert_nothing_raised("Could not create provider instance by name") do - resource = @type.new :name => "yay", :provider => :testing - end - - assert_instance_of(provider, resource.provider, "Did not create provider instance") - - # Now make sure we can pass in an instance - provinst = provider.new(:name => "foo") - assert_nothing_raised("Could not pass in provider instance") do - resource = @type.new :name => "foo", :provider => provinst - end - - assert_equal(provinst, resource.provider, "Did not retain provider instance") - assert_equal(provider.name, resource[:provider], "Provider value was set to the provider instead of its name") - - # Now make sure unsuitable provider instances still throw errors - provider = @type.provide(:badprov) do - confine :exists => "/no/such/file" - end - - # And make sure the provider must be a valid provider type for this resource - pkgprov = Puppet::Type.type(:package).new(:name => "yayness").provider - assert(provider, "did not get package provider") - - assert_raise(Puppet::Error, "Did not fail on invalid provider instance") do - resource = @type.new :name => "bar", :provider => pkgprov - end - - end -end diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb deleted file mode 100755 index c2e6a0c1e..000000000 --- a/test/ral/manager/type.rb +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'mocha' -require 'puppettest' - -class TestType < Test::Unit::TestCase - include PuppetTest - def test_typemethods - Puppet::Type.eachtype { |type| - name = nil - assert_nothing_raised("Searching for name for #{type} caused failure") { - name = type.name - } - - assert(name, "Could not find name for #{type}") - - - assert_equal( - - type, - Puppet::Type.type(name), - - "Failed to retrieve #{name} by name" - ) - - # Skip types with no parameters or valid properties - #unless ! type.parameters.empty? or ! type.validproperties.empty? - # next - #end - - assert_nothing_raised { - - assert_not_nil( - - type.properties, - - "Properties for #{name} are nil" - ) - - - assert_not_nil( - - type.validproperties, - - "Valid properties for #{name} are nil" - ) - } - } - end - - def test_aliases_are_added_to_catalog - - resource = Puppet::Type.type(:file).new( - - :name => "/path/to/some/missing/file", - - :ensure => "file" - ) - resource.stubs(:path).returns("") - - catalog = stubs 'catalog' - catalog.stubs(:resource).returns(nil) - catalog.expects(:alias).with(resource, "funtest") - resource.catalog = catalog - - assert_nothing_raised("Could not add alias") { - resource[:alias] = "funtest" - } - end - - def test_aliasing_fails_without_a_catalog - - resource = Puppet::Type.type(:file).new( - - :name => "/no/such/file", - - :ensure => "file" - ) - - assert_raise(Puppet::Error, "It should fail to alias when no catalog was available") { - resource[:alias] = "funtest" - } - end - - def test_ensuredefault - user = nil - assert_nothing_raised { - - user = Puppet::Type.type(:user).new( - - :name => "pptestAA", - - :check => [:uid] - ) - } - - # make sure we don't get :ensure for unmanaged files - assert(! user.property(:ensure), "User got an ensure property") - - assert_nothing_raised { - - user = Puppet::Type.type(:user).new( - - :name => "pptestAB", - - :comment => "Testingness" - ) - } - # but make sure it gets added once we manage them - assert(user.property(:ensure), "User did not add ensure property") - - assert_nothing_raised { - - user = Puppet::Type.type(:user).new( - - :name => "pptestBC", - - :comment => "A fake user" - ) - } - - # and make sure managed objects start with them - assert(user.property(:ensure), "User did not get an ensure property") - end - def test_newtype_methods - assert_nothing_raised { - Puppet::Type.newtype(:mytype) do - newparam(:wow) do isnamevar end - end - } - - - assert( - Puppet::Type.respond_to?(:newmytype), - - "new method did not get created") - - obj = nil - assert_nothing_raised { - obj = Puppet::Type.newmytype(:wow => "yay") - } - - assert(obj.is_a?(Puppet::Type.type(:mytype)), - "Obj is not the correct type") - - # Now make the type again, just to make sure it works on refreshing. - assert_nothing_raised { - Puppet::Type.newtype(:mytype) do - newparam(:yay) do isnamevar end - end - } - - obj = nil - # Make sure the old class was thrown away and only the new one is sitting - # around. - assert_raise(Puppet::Error) { - obj = Puppet::Type.newmytype(:wow => "yay") - } - assert_nothing_raised { - obj = Puppet::Type.newmytype(:yay => "yay") - } - - # Now make sure that we don't replace existing, non-type methods - parammethod = Puppet::Type.method(:newparam) - - assert_nothing_raised { - Puppet::Type.newtype(:param) do - newparam(:rah) do isnamevar end - end - } - assert_equal(parammethod, Puppet::Type.method(:newparam), "newparam method got replaced by newtype") - end - - def test_newproperty_options - # Create a type with a fake provider - providerclass = Class.new do - def self.supports_parameter?(prop) - true - end - def method_missing(method, *args) - method - end - end - self.class.const_set("ProviderClass", providerclass) - - type = Puppet::Type.newtype(:mytype) do - newparam(:name) do - isnamevar - end - def provider - @provider ||= ProviderClass.new - - @provider - end - end - - # Now make a property with no options. - property = nil - assert_nothing_raised do - property = type.newproperty(:noopts) do - end - end - - # Now create an instance - obj = type.create(:name => :myobj) - - inst = property.new(:resource => obj) - - # And make sure it's correctly setting @is - ret = nil - assert_nothing_raised { - ret = inst.retrieve - } - - assert_equal(:noopts, inst.retrieve) - - # Now create a property with a different way of doing it - property = nil - assert_nothing_raised do - property = type.newproperty(:setretrieve, :retrieve => :yayness) - end - - inst = property.new(:resource => obj) - - # And make sure it's correctly setting @is - ret = nil - assert_nothing_raised { - ret = inst.retrieve - } - - assert_equal(:yayness, ret) - end - - # Make sure the title is sufficiently differentiated from the namevar. - def test_title_at_creation_with_hash - file = nil - fileclass = Puppet::Type.type(:file) - - path = tempfile - assert_nothing_raised do - - file = fileclass.create( - - :title => "Myfile", - - :path => path - ) - end - - assert_equal("Myfile", file.title, "Did not get correct title") - assert_equal(path, file[:name], "Did not get correct name") - - file = nil - - # Now make sure we can specify both and still get the right answers - assert_nothing_raised do - - file = fileclass.create( - - :title => "Myfile", - - :name => path - ) - end - - assert_instance_of(fileclass, file) - - assert_equal("Myfile", file.title, "Did not get correct title") - assert_equal(path, file[:name], "Did not get correct name") - end - - # Make sure that we can have multiple non-isomorphic objects with the same name, - # but not with isomorphic objects. - def test_isomorphic_names - catalog = mk_catalog - # First do execs, since they're not isomorphic. - echo = Puppet::Util.which "echo" - exec1 = exec2 = nil - assert_nothing_raised do - - exec1 = Puppet::Type.type(:exec).new( - - :title => "exec1", - - :command => "#{echo} funtest" - ) - end - catalog.add_resource(exec1) - assert_nothing_raised do - - exec2 = Puppet::Type.type(:exec).new( - - :title => "exec2", - - :command => "#{echo} funtest" - ) - end - catalog.add_resource(exec2) - - # Now do files, since they are. This should fail. - file1 = file2 = nil - path = tempfile - - file1 = Puppet::Type.type(:file).new( - - :title => "file1", - :path => path, - - :content => "yayness" - ) - catalog.add_resource(file1) - - - file2 = Puppet::Type.type(:file).new( - - :title => "file2", - :path => path, - - :content => "rahness" - ) - assert_raise(ArgumentError) { catalog.add_resource(file2) } - end - - def test_tags - obj = Puppet::Type.type(:file).new(:path => tempfile) - - tags = ["some", "test", "tags"] - - obj.tags = tags - - # tags can be stored in an unordered set, so we sort - # them for the assert_equal to work - assert_equal((tags << "file").sort, obj.tags.sort) - end - - def test_to_hash - file = Puppet::Type.newfile :path => tempfile, :owner => "luke", - :recurse => true, :loglevel => "warning" - - hash = nil - assert_nothing_raised do - hash = file.to_hash - end - - [:path, :owner, :recurse, :loglevel].each do |param| - assert(hash[param], "Hash did not include #{param}") - end - end - - def test_ref - path = tempfile - Puppet::Type.type(:exec) # uggh, the methods need to load the types - file = Puppet::Type.newfile(:path => path) - assert_equal("File[#{path}]", file.ref) - - exec = Puppet::Type.newexec(:title => "yay", :command => "/bin/echo yay") - assert_equal("Exec[yay]", exec.ref) - end -end diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb deleted file mode 100755 index 0bdb94b3b..000000000 --- a/test/ral/providers/cron/crontab.rb +++ /dev/null @@ -1,652 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' -require 'mocha' -require 'puppettest/fileparsing' - -class TestCronParsedProvider < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - - FIELDS = { - :crontab => %w{command minute hour month monthday weekday}.collect { |o| o.intern }, - :freebsd_special => %w{special command}.collect { |o| o.intern }, - :environment => [:line], - :blank => [:line], - :comment => [:line], - } - - # These are potentially multi-line records; there's no one-to-one map, but they model - # a full cron job. These tests assume individual record types will always be correctly - # parsed, so all they - def sample_crons - @sample_crons ||= YAML.load(File.read(File.join(@crondir, "crontab_collections.yaml"))) - end - - # These are simple lines that can appear in the files; there is a one to one - # mapping between records and lines. We have plenty of redundancy here because - # we use these records to build up our complex, multi-line cron jobs below. - def sample_records - @sample_records ||= YAML.load(File.read(File.join(@crondir, "crontab_sample_records.yaml"))) - end - - def setup - super - @type = Puppet::Type.type(:cron) - @provider = @type.provider(:crontab) - @provider.initvars - @crondir = datadir(File.join(%w{providers cron})) - - @oldfiletype = @provider.filetype - end - - def teardown - Puppet::Util::FileType.filetype(:ram).clear - @provider.clear - super - end - - # Make sure a cron job matches up. Any non-passed fields are considered absent. - def assert_cron_equal(msg, cron, options) - assert_instance_of(@provider, cron, "not an instance of provider in #{msg}") - options.each do |param, value| - assert_equal(value, cron.send(param), "#{param} was not equal in #{msg}") - end - %w{command environment minute hour month monthday weekday}.each do |var| - assert_equal(:absent, cron.send(var), "#{var} was not parsed absent in #{msg}") unless options.include?(var.intern) - end - end - - # Make sure a cron record matches. This only works for crontab records. - def assert_record_equal(msg, record, options) - raise ArgumentError, "You must pass the required record type" unless options.include?(:record_type) - assert_instance_of(Hash, record, "not an instance of a hash in #{msg}") - options.each do |param, value| - assert_equal(value, record[param], "#{param} was not equal in #{msg}") - end - FIELDS[record[:record_type]].each do |var| - assert_equal(:absent, record[var], "#{var} was not parsed absent in #{msg}") unless options.include?(var) - end - end - - def assert_header(file) - header = [] - file.gsub! /^(# HEADER: .+$)\n/ do - header << $1 - '' - end - assert_equal(4, header.length, "Did not get four header lines") - end - - # This handles parsing every possible iteration of cron records. Note that this is only - # single-line stuff and doesn't include multi-line values (e.g., with names and/or envs). - # Those have separate tests. - def test_parse_line - # First just do each sample record one by one - sample_records.each do |name, options| - result = nil - assert_nothing_raised("Could not parse #{name}: '#{options[:text]}'") do - result = @provider.parse_line(options[:text]) - end - assert_record_equal("record for #{name}", result, options[:record]) - end - - # Then do them all at once. - records = [] - text = "" - # Sort sample_records so that the :empty entry does not come last - # (if it does, the test will fail because the empty last line will - # be ignored) - sample_records.sort { |a, b| a.first.to_s <=> b.first.to_s }.each do |name, options| - records << options[:record] - text += options[:text] + "\n" - end - - result = nil - assert_nothing_raised("Could not match all records in one file") do - result = @provider.parse(text) - end - - records.zip(result).each do |should, record| - assert_record_equal("record for #{should.inspect} in full match", record, should) - end - end - - # Here we test that each record generates to the correct text. - def test_generate_line - # First just do each sample record one by one - sample_records.each do |name, options| - result = nil - assert_nothing_raised("Could not generate #{name}: '#{options[:record]}'") do - result = @provider.to_line(options[:record]) - end - assert_equal(options[:text], result, "Did not generate correct text for #{name}") - end - - # Then do them all at once. - records = [] - text = "" - sample_records.each do |name, options| - records << options[:record] - text += options[:text] + "\n" - end - - result = nil - assert_nothing_raised("Could not match all records in one file") do - result = @provider.to_file(records) - end - - assert_header(result) - - assert_equal(text, result, "Did not generate correct full crontab") - end - - # Test cronjobs that are made up from multiple records. - def test_multi_line_cronjobs - fulltext = "" - all_records = [] - sample_crons.each do |name, record_names| - records = record_names.collect do |record_name| - unless record = sample_records[record_name] - raise "Could not find sample record #{record_name}" - end - record - end - - text = records.collect { |r| r[:text] }.join("\n") + "\n" - record_list = records.collect { |r| r[:record] } - - # Add it to our full collection - all_records += record_list - fulltext += text - - # First make sure we generate each one correctly - result = nil - assert_nothing_raised("Could not generate multi-line cronjob #{name}") do - result = @provider.to_file(record_list) - end - assert_header(result) - assert_equal(text, result, "Did not generate correct text for multi-line cronjob #{name}") - - # Now make sure we parse each one correctly - assert_nothing_raised("Could not parse multi-line cronjob #{name}") do - result = @provider.parse(text) - end - record_list.zip(result).each do |should, record| - assert_record_equal("multiline cronjob #{name}", record, should) - end - end - - # Make sure we can generate it all correctly - result = nil - assert_nothing_raised("Could not generate all multi-line cronjobs") do - result = @provider.to_file(all_records) - end - assert_header(result) - assert_equal(fulltext, result, "Did not generate correct text for all multi-line cronjobs") - - # Now make sure we parse them all correctly - assert_nothing_raised("Could not parse multi-line cronjobs") do - result = @provider.parse(fulltext) - end - all_records.zip(result).each do |should, record| - assert_record_equal("multiline cronjob %s", record, should) - end - end - - # Take our sample files, and make sure we can entirely parse them, - # then that we can generate them again and we get the same data. - def test_parse_and_generate_sample_files - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - crondir = datadir(File.join(%w{providers cron})) - files = Dir.glob("#{crondir}/crontab.*") - - setme - @provider.default_target = @me - target = @provider.target_object(@me) - files.each do |file| - str = args = nil - assert_nothing_raised("could not load #{file}") do - str, args = YAML.load(File.read(file)) - end - - # Stupid old yaml - args.each do |hash| - hash.each do |param, value| - if param.is_a?(String) and param =~ /^:/ - hash.delete(param) - param = param.sub(/^:/,'').intern - hash[param] = value - end - - if value.is_a?(String) and value =~ /^:/ - value = value.sub(/^:/,'').intern - hash[param] = value - end - end - end - target.write(str) - assert_nothing_raised("could not parse #{file}") do - @provider.prefetch - end - records = @provider.send(:instance_variable_get, "@records") - - args.zip(records) do |should, sis| - # Make the values a bit more equal. - should[:target] = @me - should[:ensure] = :present - #should[:environment] ||= [] - should[:on_disk] = true - is = sis.dup - sis.dup.each do |p,v| - is.delete(p) if v == :absent - end - - assert_equal( - should, is, - - "Did not parse #{file} correctly") - end - - assert_nothing_raised("could not generate #{file}") do - @provider.flush_target(@me) - end - - assert_equal(str, target.read, "#{file} changed") - @provider.clear - end - end - - # A simple test to see if we can load the cron from disk. - def test_load - setme - records = nil - assert_nothing_raised { - records = @provider.retrieve(@me) - } - assert_instance_of(Array, records, "did not get correct response") - end - - # Test that a cron job turns out as expected, by creating one and generating - # it directly - def test_simple_to_cron - # make the cron - setme - - name = "yaytest" - args = {:name => name, - :command => "date > /dev/null", - :minute => "30", - :user => @me, - :record_type => :crontab - } - # generate the text - str = nil - assert_nothing_raised { - str = @provider.to_line(args) - } - - - assert_equal( - "# Puppet Name: #{name}\n30 * * * * date > /dev/null", str, - - "Cron did not generate correctly") - end - - # Test that comments are correctly retained - def test_retain_comments - str = "# this is a comment\n#and another comment\n" - user = "fakeuser" - records = nil - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - target = @provider.target_object(user) - target.write(str) - assert_nothing_raised { - @provider.prefetch - } - - assert_nothing_raised { - newstr = @provider.flush_target(user) - assert(target.read.include?(str), "Comments were lost") - } - end - - def test_simpleparsing - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - text = "5 1,2 * 1 0 /bin/echo funtest" - - records = nil - assert_nothing_raised { - records = @provider.parse(text) - } - - should = { - :minute => %w{5}, - :hour => %w{1 2}, - :monthday => :absent, - :month => %w{1}, - :weekday => %w{0}, - :command => "/bin/echo funtest" - } - - is = records.shift - assert(is, "Did not get record") - - should.each do |p, v| - assert_equal(v, is[p], "did not parse #{p} correctly") - end - end - - # Make sure we can create a cron in an empty tab. - # LAK:FIXME This actually modifies the user's crontab, - # which is pretty heinous. - def test_mkcron_if_empty - setme - @provider.filetype = @oldfiletype - - records = @provider.retrieve(@me) - - target = @provider.target_object(@me) - - cleanup do - if records.length == 0 - target.remove - else - target.write(@provider.to_file(records)) - end - end - - # Now get rid of it - assert_nothing_raised("Could not remove cron tab") do - target.remove - end - - @provider.flush :target => @me, :command => "/do/something", - :record_type => :crontab - created = @provider.retrieve(@me) - assert(created.detect { |r| r[:command] == "/do/something" }, "Did not create cron tab") - end - - # Make sure we correctly bidirectionally parse things. - def test_records_and_strings - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - setme - - target = @provider.target_object(@me) - - [ - " FOO=var", - "* * * * * /some/command", - "0,30 * * * * /some/command", - "0-30 * * * * /some/command", - "# Puppet Name: name\n0-30 * * * * /some/command", - "# Puppet Name: name\nVAR=VALUE\n0-30 * * * * /some/command", - "# Puppet Name: name\nVAR=VALUE\nC=D\n0-30 * * * * /some/command", - "0 * * * * /some/command" - ].each do |str| - @provider.initvars - str += "\n" - target.write(str) - - assert_equal( - str, target.read, - - "Did not write correctly") - assert_nothing_raised("Could not prefetch with #{str.inspect}") do - @provider.prefetch - end - assert_nothing_raised("Could not flush with #{str.inspect}") do - @provider.flush_target(@me) - end - - - assert_equal( - str, target.read, - - "Changed in read/write") - - @provider.clear - end - end - - # Test that a specified cron job will be matched against an existing job - # with no name, as long as all fields match - def test_matchcron - mecron = "0,30 * * * * date - - * * * * * funtest - # a comment - 0,30 * * 1 * date - " - - youcron = "0,30 * * * * date - - * * * * * yaytest - # a comment - 0,30 * * 1 * fooness - " - setme - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - you = "you" - - # Write the same tab to multiple targets - @provider.target_object(@me).write(mecron.gsub(/^\s+/, '')) - @provider.target_object(you).write(youcron.gsub(/^\s+/, '')) - - # Now make some crons that should match - matchers = [ - - @type.new( - - :name => "yaycron", - :minute => [0, 30], - :command => "date", - - :user => @me - ), - - @type.new( - - :name => "youtest", - :command => "yaytest", - - :user => you - ) - ] - - nonmatchers = [ - - @type.new( - - :name => "footest", - :minute => [0, 30], - :hour => 1, - :command => "fooness", - - :user => @me # wrong target - ), - - @type.new( - - :name => "funtest2", - :command => "funtest", - - :user => you # wrong target for this cron - ) - ] - - # Create another cron so we prefetch two of them - @type.new(:name => "testing", :minute => 30, :command => "whatever", :user => "you") - - assert_nothing_raised("Could not prefetch cron") do - @provider.prefetch([matchers, nonmatchers].flatten.inject({}) { |crons, cron| crons[cron.name] = cron; crons }) - end - - matchers.each do |cron| - assert_equal(:present, cron.provider.ensure, "Cron #{cron.name} was not matched") - if value = cron.value(:minute) and value == "*" - value = :absent - end - assert_equal(value, cron.provider.minute, "Minutes were not retrieved, so cron was not matched") - assert_equal(cron.value(:target), cron.provider.target, "Cron #{cron.name} was matched from the wrong target") - end - - nonmatchers.each do |cron| - assert_equal(:absent, cron.provider.ensure, "Cron #{cron.name} was incorrectly matched") - end - end - - def test_data - setme - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - target = @provider.target_object(@me) - fakedata("data/providers/cron/examples").each do |file| - text = File.read(file) - target.write(text) - - assert_nothing_raised("Could not parse #{file}") do - @provider.prefetch - end - # mark the provider modified - @provider.modified(@me) - - # and zero the text - target.write("") - - result = nil - assert_nothing_raised("Could not generate #{file}") do - @provider.flush_target(@me) - end - - # Ignore whitespace differences, since those don't affect function. - modtext = text.gsub(/[ \t]+/, " ") - modtarget = target.read.gsub(/[ \t]+/, " ") - assert_equal(modtext, modtarget, "File was not rewritten the same") - - @provider.clear - end - end - - # Match freebsd's annoying @daily stuff. - def test_match_freebsd_special - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - setme - - target = @provider.target_object(@me) - - [ - "@daily /some/command", - "@daily /some/command more" - ].each do |str| - @provider.initvars - str += "\n" - target.write(str) - assert_nothing_raised("Could not prefetch with #{str.inspect}") do - @provider.prefetch - end - records = @provider.send(:instance_variable_get, "@records") - records.each do |r| - - assert_equal( - :freebsd_special, r[:record_type], - - "Did not create lines as freebsd lines") - end - assert_nothing_raised("Could not flush with #{str.inspect}") do - @provider.flush_target(@me) - end - - - assert_equal( - str, target.read, - - "Changed in read/write") - - @provider.clear - end - end - - # #707 - def test_write_freebsd_special - assert_equal(@provider.to_line(:record_type => :crontab, :ensure => :present, :special => "reboot", :command => "/bin/echo something"), "@reboot /bin/echo something") - end - - def test_prefetch - cron = @type.new :command => "/bin/echo yay", :name => "test", :hour => 4 - - assert_nothing_raised("Could not prefetch cron") do - cron.provider.class.prefetch("test" => cron) - end - end - - # Testing #669. - def test_environment_settings - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - setme - - target = @provider.target_object(@me) - - # First with no env settings - resource = @type.new :command => "/bin/echo yay", :name => "test", :hour => 4 - cron = resource.provider - - cron.ensure = :present - cron.command = "/bin/echo yay" - cron.hour = %w{4} - cron.flush - - result = target.read - assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write cron out correctly") - - # Now set the env - cron.environment = "TEST=foo" - cron.flush - - result = target.read - assert_equal("# Puppet Name: test\nTEST=foo\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting") - - # Modify it - cron.environment = ["TEST=foo", "BLAH=yay"] - cron.flush - - result = target.read - assert_equal("# Puppet Name: test\nTEST=foo\nBLAH=yay\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting") - - # And remove it - cron.environment = :absent - cron.flush - - result = target.read - assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting") - end - - # Testing #1216 - def test_strange_lines - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - text = " 5 \t\t 1,2 * 1 0 /bin/echo funtest" - - records = nil - assert_nothing_raised { - records = @provider.parse(text) - } - - should = { - :minute => %w{5}, - :hour => %w{1 2}, - :monthday => :absent, - :month => %w{1}, - :weekday => %w{0}, - :command => "/bin/echo funtest" - } - - is = records.shift - assert(is, "Did not get record") - - should.each do |p, v| - assert_equal(v, is[p], "did not parse #{p} correctly") - end - end -end diff --git a/test/ral/providers/group.rb b/test/ral/providers/group.rb deleted file mode 100755 index 4259be355..000000000 --- a/test/ral/providers/group.rb +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'etc' - -class TestGroupProvider < Test::Unit::TestCase - include PuppetTest - def setup - super - @@tmpgroups = [] - @provider = nil - assert_nothing_raised { - @provider = Puppet::Type.type(:group).defaultprovider - } - - assert(@provider, "Could not find default group provider") - assert(@provider.name != :fake, "Got a fake provider") - end - - def teardown - super - @@tmpgroups.each { |group| - remove(group) unless missing?(group) - } - end - - def mkgroup(name, hash = {}) - fakeresource = stub 'group', :allowdupe? => false, :name => name - fakeresource.stubs(:[]).returns nil - fakeresource.stubs(:should).returns nil - fakeresource.stubs(:[]).with(:name).returns name - hash.each do |name, val| - fakeresource.stubs(:should).with(name).returns val - fakeresource.stubs(:[]).with(name).returns val - end - group = nil - assert_nothing_raised { - group = @provider.new(fakeresource) - } - assert(group, "Could not create provider group") - - group - end - - case Facter["operatingsystem"].value - when "Darwin" - def missing?(group) - output = %x{nidump -r /groups/#{group} / 2>/dev/null}.chomp - - return output == "" - - assert_equal("", output, "Group #{group} is present:\n#{output}") - end - - def gid(name) - %x{nireport / /groups name gid}.split("\n").each { |line| - group, id = line.chomp.split(/\s+/) - assert(id =~ /^-?\d+$/, "Group id #{id.inspect} for #{group} is not a number") - if group == name - return Integer(id) - end - } - - nil - end - - def remove(group) - system("niutil -destroy / /groups/#{group}") - end - else - def missing?(group) - obj = Etc.getgrnam(group) - return false - rescue ArgumentError - return true - end - - def gid(name) - assert_nothing_raised { - obj = Etc.getgrnam(name) - return obj.gid - } - - nil - end - - def remove(group) - system("groupdel #{group}") - end - end - - def groupnames - %x{groups}.chomp.split(/ /) - end - - def groupids - Process.groups - end - - def attrtest_ensure(group) - old = group.ensure - assert_nothing_raised { - group.delete - } - - assert(!group.exists?, "Group was not deleted") - - assert_nothing_raised { - group.create - } - assert(group.exists?, "Group was not created") - - unless old == :present - assert_nothing_raised { - group.delete - } - end - end - - def attrtest_gid(group) - old = gid(group.name) - - newgid = old - while true - newgid += 1 - - if newgid - old > 1000 - $stderr.puts "Could not find extra test UID" - return - end - begin - Etc.getgrgid(newgid) - rescue ArgumentError => detail - break - end - end - - assert_nothing_raised("Failed to change group id") { - group.gid = newgid - } - - curgid = nil - assert_nothing_raised { - curgid = gid(group.name) - } - - assert_equal(newgid, curgid, "GID was not changed") - # Refresh - group.getinfo(true) - assert_equal(newgid, group.gid, "Object got wrong gid") - - assert_nothing_raised("Failed to change group id") { - group.gid = old - } - end - - # Iterate over each of our groups and try to grab the gid. - def test_ownprovidergroups - groupnames.each { |group| - gobj = nil - comp = nil - fakeresource = fakeresource(:group, group) - assert_nothing_raised { - gobj = @provider.new(fakeresource) - } - - assert(gobj.gid, "Failed to retrieve gid") - } - end - - if Puppet.features.root? - def test_mkgroup - gobj = nil - comp = nil - name = "pptestgr" - assert(missing?(name), "Group #{name} is still present") - group = mkgroup(name) - - @@tmpgroups << name - - assert(group.respond_to?(:addcmd), "no respondo?") - assert_nothing_raised { - group.create - } - assert(!missing?(name), "Group #{name} is missing") - - tests = Puppet::Type.type(:group).validproperties - - tests.each { |test| - if self.respond_to?("attrtest_#{test}") - self.send("attrtest_#{test}", group) - else - $stderr.puts "Not testing attr #{test} of group" - end - } - - assert_nothing_raised { - group.delete - } - end - - # groupadd -o is broken in FreeBSD. - unless Facter["operatingsystem"].value == "FreeBSD" - def test_duplicateIDs - group1 = mkgroup("group1", :gid => 125) - - @@tmpgroups << "group1" - @@tmpgroups << "group2" - # Create the first group - assert_nothing_raised { - group1.create - } - - # Not all OSes fail here, so we can't test that it doesn't work with - # it off, only that it does work with it on. - group2 = mkgroup("group2", :gid => 125) - group2.resource.stubs(:allowdupe?).returns true - - # Now create the second group - assert_nothing_raised { - group2.create - } - assert_equal(:present, group2.ensure, "Group did not get created") - end - end - else - $stderr.puts "Not running as root; skipping group creation tests." - end - - def test_autogen - provider = nil - group = Puppet::Type.type(:group).new(:name => nonrootgroup.name) - provider = group.provider - assert(provider, "did not get provider") - - # Everyone should be able to autogenerate a uid - assert_instance_of(Fixnum, provider.autogen(:gid)) - end -end - diff --git a/test/ral/providers/host/parsed.rb b/test/ral/providers/host/parsed.rb deleted file mode 100755 index 521654d53..000000000 --- a/test/ral/providers/host/parsed.rb +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' -require 'puppettest/fileparsing' -require 'test/unit' - -class TestParsedHostProvider < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - def setup - super - @provider = Puppet::Type.type(:host).provider(:parsed) - - @oldfiletype = @provider.filetype - end - - def teardown - Puppet::Util::FileType.filetype(:ram).clear - @provider.filetype = @oldfiletype - @provider.clear - super - end - - # Parse our sample data and make sure we regenerate it correctly. - def test_hostsparse - fakedata("data/types/hosts").each do |file| fakedataparse(file) end - end -end - diff --git a/test/ral/providers/mailalias/aliases.rb b/test/ral/providers/mailalias/aliases.rb deleted file mode 100755 index 9cd2fc354..000000000 --- a/test/ral/providers/mailalias/aliases.rb +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' -require 'puppettest/fileparsing' - -class TestMailaliasAliasesProvider < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - def setup - super - @provider = Puppet::Type.type(:mailalias).provider(:aliases) - - @oldfiletype = @provider.filetype - - @alias = mkalias - end - - def teardown - Puppet::Util::FileType.filetype(:ram).clear - @provider.filetype = @oldfiletype - @provider.clear - super - end - - def mkalias(name = "me") - if defined?(@pcount) - @pcount += 1 - else - @pcount = 1 - end - args = { - :name => name, - :recipient => %w{here there} - } - - fakeresource = fakeresource(:mailalias, args[:name]) - - key = @provider.new(fakeresource) - args.each do |p,v| - key.send(p.to_s + "=", v) - end - - key - end - - def test_data_parsing_and_generating - fakedata("data/types/mailalias").each { |file| - fakedataparse(file) - } - end -end - diff --git a/test/ral/providers/nameservice.rb b/test/ral/providers/nameservice.rb deleted file mode 100755 index a04b45b1f..000000000 --- a/test/ral/providers/nameservice.rb +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'puppet/provider/nameservice' -require 'facter' - -class TestNameServiceProvider < Test::Unit::TestCase - include PuppetTest::FileTesting - - def test_option - klass = Class.new(Puppet::Provider::NameService) - klass.resource_type = Puppet::Type.type(:user) - - val = nil - assert_nothing_raised { - val = klass.option(:home, :flag) - } - - assert_nil(val, "Got an option") - - assert_nothing_raised { - klass.options :home, :flag => "-d" - } - assert_nothing_raised { - val = klass.option(:home, :flag) - } - assert_equal("-d", val, "Got incorrect option") - end -end - diff --git a/test/ral/providers/package.rb b/test/ral/providers/package.rb deleted file mode 100755 index 5264443bc..000000000 --- a/test/ral/providers/package.rb +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'etc' - -class TestPackageProvider < Test::Unit::TestCase - include PuppetTest - - def setup - super - Puppet.info @method_name - end - - # Load the testpackages hash. - def self.load_test_packages - require 'yaml' - file = File.join(PuppetTest.datadir, "providers", "package", "testpackages.yaml") - raise "Could not find file #{file}" unless FileTest.exists?(file) - array = YAML::load(File.read(file)).collect { |hash| - # Stupid ruby 1.8.1. YAML is sometimes broken such that - # symbols end up being strings with the : in them. - hash.each do |name, value| - if name.is_a?(String) and name =~ /^:/ - hash.delete(name) - name = name.sub(/^:/, '').intern - hash[name] = value - end - if value.is_a?(String) and value =~ /^:/ - hash[name] = value.sub(/^:/, '').intern - end - end - } - - array - end - - def self.suitable_test_packages - list = load_test_packages - providers = {} - Puppet::Type.type(:package).suitableprovider.each do |provider| - providers[provider.name] = provider - end - facts = {} - Facter.to_hash.each do |fact, value| - facts[fact.to_s.downcase.intern] = value.to_s.downcase.intern - end - list.find_all { |hash| # First find the matching providers - hash.include?(:provider) and providers.include?(hash[:provider]) - }.reject { |hash| # Then find matching fact sets - facts.detect do |fact, value| - # We're detecting unmatched facts, but we also want to - # delete the facts so they don't show up later. - if fval = hash[fact] - hash.delete(fact) - fval = [fval] unless fval.is_a?(Array) - fval = fval.collect { |v| v.downcase.intern } - ! fval.include?(value) - end - end - } - end - - def assert_absent(provider, msg = "package not absent") - result = nil - assert_nothing_raised("Could not query provider") do - result = provider.query - end - if result.nil? - assert_nil(result) - elsif result.is_a?(Hash) - assert (result[:ensure] == :absent or result[:ensure] == :purged), msg - else - raise "dunno how to handle #{result.inspect}" - end - end - - def assert_not_absent(provider, msg = "package not installed") - result = nil - assert_nothing_raised("Could not query provider") do - result = provider.query - end - assert((result == :listed or result.is_a?(Hash)), "query did not return hash or :listed") - if result == :listed - assert(provider.resource.is(:ensure) != :absent, msg) - else - assert(result[:ensure] != :absent, msg) - end - end - - # Run a package through all of its paces. FIXME This should use the - # provider, not the package, duh. - def run_package_installation_test(hash) - # Turn the hash into a package - if files = hash[:files] - hash.delete(:files) - if files.is_a?(Array) - hash[:source] = files.shift - else - hash[:source] = files - files = [] - end - else - files = [] - end - - if versions = hash[:versions] - hash.delete(:versions) - else - versions = [] - end - - # Start out by just making sure it's installed - if versions.empty? - hash[:ensure] = :present - else - hash[:ensure] = versions.shift - end - - if hash[:source] - unless FileTest.exists?(hash[:source]) - $stderr.puts "Create a package at #{hash[:source]} for testing" - return - end - end - - if cleancmd = hash[:cleanup] - hash.delete(:cleanup) - end - - pkg = nil - assert_nothing_raised( - "Could not turn #{hash.inspect} into a package" - ) do - pkg = Puppet::Type.newpackage(hash) - end - - # Make any necessary modifications. - modpkg(pkg) - - provider = pkg.provider - - assert(provider, "Could not retrieve provider") - - return if result = provider.query and ! [:absent, :purged].include?(result[:ensure]) - - assert_absent(provider) - - if Process.uid != 0 - Puppet.info "Run as root for full package tests" - return - end - - cleanup do - if pkg.provider.respond_to?(:uninstall) - pkg.provider.flush - if pkg.provider.properties[:ensure] != :absent - assert_nothing_raised("Could not clean up package") do - pkg.provider.uninstall - end - end - else - system(cleancmd) if cleancmd - end - end - - # Now call 'latest' after the package is installed - if provider.respond_to?(:latest) - assert_nothing_raised("Could not call 'latest'") do - provider.latest - end - end - - assert_nothing_raised("Could not install package") do - provider.install - end - - assert_not_absent(provider, "package did not install") - - # If there are any remaining files, then test upgrading from there - unless files.empty? - pkg[:source] = files.shift - current = provider.properties - assert_nothing_raised("Could not upgrade") do - provider.update - end - provider.flush - new = provider.properties - assert(current != new, "package was not upgraded: #{current.inspect} did not change") - end - - unless versions.empty? - pkg[:ensure] = versions.shift - current = provider.properties - assert_nothing_raised("Could not upgrade") do - provider.update - end - provider.flush - new = provider.properties - assert(current != new, "package was not upgraded: #{current.inspect} did not change") - end - - # Now call 'latest' after the package is installed - if provider.respond_to?(:latest) - assert_nothing_raised("Could not call 'latest'") do - provider.latest - end - end - - # Now remove the package - if provider.respond_to?(:uninstall) - assert_nothing_raised do - provider.uninstall - end - - assert_absent(provider) - end - end - - # Now create a separate test method for each package - suitable_test_packages.each do |hash| - mname = ["test", hash[:name].to_s, hash[:provider].to_s].join("_").intern - - if method_defined?(mname) - warn "Already a test method defined for #{mname}" - else - define_method(mname) do - run_package_installation_test(hash) - end - end - end - - def test_dont_complain_if_theres_nothing_to_test - assert("sometimes the above metaprogramming fails to find anything to test and the runner complains") - end - - def modpkg(pkg) - case pkg[:provider] - when :sun - pkg[:adminfile] = "/usr/local/pkg/admin_file" - end - end -end - diff --git a/test/ral/providers/package/aptitude.rb b/test/ral/providers/package/aptitude.rb deleted file mode 100755 index 871de9ded..000000000 --- a/test/ral/providers/package/aptitude.rb +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'mocha' - -class AptitudePackageProviderTest < PuppetTest::TestCase - include PuppetTest - - confine "Aptitude package provider missing" => - Puppet::Type.type(:package).provider(:aptitude).suitable? - - def setup - super - @type = Puppet::Type.type(:package) - end - - def test_install - pkg = @type.new :name => 'faff', - :provider => :aptitude, - :ensure => :present, - :source => "/tmp/faff.deb" - - pkg.provider.expects( - :dpkgquery - - ).with( - - '-W', - '--showformat', - '${Status} ${Package} ${Version}\n', - - 'faff' - ).returns( - "deinstall ok config-files faff 1.2.3-1\n" - ).times(1) - - pkg.provider.expects( - :aptitude - - ).with( - - '-y', - '-o', - 'DPkg::Options::=--force-confold', - :install, - - 'faff' - ).returns(0) - - assert_apply( pkg ) - end - - def test_purge - pkg = @type.new :name => 'faff', :provider => :aptitude, :ensure => :purged - - pkg.provider.expects( - :dpkgquery - - ).with( - - '-W', - '--showformat', - '${Status} ${Package} ${Version}\n', - - 'faff' - ).returns( - "install ok installed faff 1.2.3-1\n" - ).times(1) - pkg.provider.expects( - :aptitude - - ).with( - - '-y', - 'purge', - - 'faff' - ).returns(0) - - assert_apply( pkg ) - end -end diff --git a/test/ral/providers/package/aptrpm.rb b/test/ral/providers/package/aptrpm.rb deleted file mode 100755 index a9646696a..000000000 --- a/test/ral/providers/package/aptrpm.rb +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'mocha' - -class AptrpmPackageProviderTest < PuppetTest::TestCase - confine "Apt package provider missing" => - Puppet::Type.type(:package).provider(:aptrpm).suitable? - - def setup - super - @type = Puppet::Type.type(:package) - end - - def test_install - pkg = @type.new :name => 'faff', - :provider => :aptrpm, - :ensure => :present, - :source => "/tmp/faff.rpm" - - pkg.provider.expects( - :rpm - - ).with( - - '-q', - 'faff', - '--nosignature', - '--nodigest', - '--qf', - - "%{NAME}-%{VERSION}-%{RELEASE} %{VERSION}-%{RELEASE}\n" - ).raises(Puppet::ExecutionFailure, "couldn't find rpm").times(1) - - pkg.provider.expects( - :aptget - - ).with( - - '-q', - '-y', - "install", - - 'faff' - ).returns(0) - - pkg.evaluate.each { |state| state.forward } - end - - def test_uninstall - pkg = @type.new :name => 'faff', :provider => :aptrpm, :ensure => :absent - - pkg.provider.expects( - :rpm - - ).with( - - '-q', - 'faff', - '--nosignature', - '--nodigest', - '--qf', - - "%{NAME}-%{VERSION}-%{RELEASE} %{VERSION}-%{RELEASE}\n" - ).returns( - "faff-1.2.3-1 1.2.3-1\n" - ).times(1) - pkg.provider.expects( - :aptget - - ).with( - - '-y', - '-q', - 'remove', - - 'faff' - ).returns(0) - - pkg.evaluate.each { |state| state.forward } - end - - # LAK: I don't know where this test will ever return true.. - def disabled_test_latest - pkg = @type.new :name => 'ssh', :provider => :aptrpm - - assert(pkg, "did not create pkg") - status = pkg.provider.query - assert(status, "ssh is not installed") - assert(status[:ensure] != :absent, "ssh is not installed") - - latest = nil - assert_nothing_raised("Could not call latest") do - latest = pkg.provider.latest - end - assert(latest, "Could not get latest value from apt") - end -end - diff --git a/test/ral/providers/parsedfile.rb b/test/ral/providers/parsedfile.rb deleted file mode 100755 index b9e33e56c..000000000 --- a/test/ral/providers/parsedfile.rb +++ /dev/null @@ -1,695 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'mocha' -require 'puppettest/fileparsing' -require 'puppet/util/filetype' -require 'puppet/provider/parsedfile' -require 'facter' - -class TestParsedFile < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - Puppet::Type.newtype(:testparsedfiletype) do - ensurable - newproperty(:one) do - newvalue(:a) - newvalue(:b) - end - newproperty(:two) do - newvalue(:c) - newvalue(:d) - end - - newparam(:name) do - end - - # The target should always be a property, not a parameter. - newproperty(:target) do - defaultto { @resource.class.defaultprovider.default_target } - end - end - - # A simple block to skip the complexity of a full transaction. - def apply(resource) - [:one, :two, :ensure, :target].each do |st| - Puppet.info "Setting #{resource[:name]}: #{st} => #{resource.should(st)}" - resource.provider.send(st.to_s + "=", resource.should(st)) - end - end - - def mkresource(name, options = {}) - options[:one] ||= "a" - options[:two] ||= "c" - options[:name] ||= name - - resource = @type.new(options) - end - - def mkprovider(name = :parsed) - @provider = @type.provide(name, :parent => Puppet::Provider::ParsedFile, :filetype => :ram, :default_target => "yayness") do - record_line name, :fields => %w{name one two} - end - end - - def setup - super - @type = Puppet::Type.type(:testparsedfiletype) - end - - def teardown - if defined?(@provider) - @type.unprovide(@provider.name) - @provider = nil - end - super - end - - def test_create_provider - assert_nothing_raised do - mkprovider - end - end - - def test_resource_attributes - prov = nil - assert_nothing_raised do - prov = mkprovider - end - - [:one, :two, :name].each do |attr| - assert(prov.method_defined?(attr), "Did not define #{attr}") - end - - # Now make sure they stay around - fakeresource = fakeresource(:testparsedfiletype, "yay") - - file = prov.new(fakeresource) - assert(file, "Could not make provider") - - assert_nothing_raised("Could not set provider name") do - file.name = :yayness - end - - # The provider converts to strings - assert_equal(:yayness, file.name) - end - - def test_filetype - prov = mkprovider - - flat = Puppet::Util::FileType.filetype(:flat) - ram = Puppet::Util::FileType.filetype(:ram) - assert_nothing_raised do - prov.filetype = :flat - end - - assert_equal(flat, prov.filetype) - - assert_nothing_raised do - prov.filetype = ram - end - assert_equal(ram, prov.filetype) - end - - # Make sure we correctly create a new filetype object, but only when - # necessary. - def test_fileobject - prov = mkprovider - - path = tempfile - obj = nil - assert_nothing_raised do - obj = prov.target_object(path) - end - - # The default filetype is 'ram' - assert_instance_of(Puppet::Util::FileType.filetype(:ram), obj) - - newobj = nil - assert_nothing_raised do - newobj = prov.target_object(path) - end - - assert_equal(obj, newobj, "did not reuse file object") - - # now make sure clear does the right thing - assert_nothing_raised do - prov.clear - end - assert_nothing_raised do - newobj = prov.target_object(path) - end - - assert(obj != newobj, "did not reuse file object") - end - - def test_retrieve - prov = mkprovider - - prov.filetype = :ram - - # Override the parse method with our own - prov.meta_def(:parse) do |text| - return [text] - end - - path = :yayness - file = prov.target_object(path) - text = "a test" - file.write(text) - - ret = nil - assert_nothing_raised do - ret = prov.retrieve(path) - end - - assert_equal([text], ret) - - # Now set the text to nil and make sure we get an empty array - file.write(nil) - assert_nothing_raised do - ret = prov.retrieve(path) - end - - assert_equal([], ret) - - # And the empty string should return an empty array - file.write("") - assert_nothing_raised do - ret = prov.retrieve(path) - end - - assert_equal([], ret) - end - - # Verify that prefetch will parse the file, create any necessary instances, - # and set the 'is' values appropriately. - def test_prefetch - prov = mkprovider - - prov.filetype = :ram - prov.default_target = :default - - # Create a couple of demo files - prov.target_object(:file1).write "bill b c\njill b d" - - prov.target_object(:default).write "will b d\n" - - # Create some resources for some of those demo files - bill = mkresource "bill", :target => :file1, :one => "b", :two => "c" - will = mkresource "will", :target => :default, :one => "b", :two => "d" - - resources = {"bill" => bill, "will" => will} - prov_ids = {"bill" => bill.provider.object_id, "will" => will.provider.object_id} - - assert_nothing_raised do - prov.prefetch(resources) - end - - assert(bill.provider.object_id != prov_ids["bill"], "provider was not replaced in resource") - assert(will.provider.object_id != prov_ids["will"], "provider was not replaced in resource") - - # Make sure we prefetched our resources. - assert_equal("b", bill.provider.one, "did not prefetch resource from file1") - assert_equal("c", bill.provider.two, "did not prefetch resource from file1") - assert_equal("b", will.provider.one, "did not prefetch resource from default") - assert_equal("d", will.provider.two, "did not prefetch resource from default") - - # Now modify our resources and write them out, making sure that prefetching - # hasn't somehow destroyed this ability - bill[:one] = "a" - will[:one] = "a" - - assert_apply(bill) - assert_apply(will) - - prov.prefetch(resources) - assert_equal("a", bill.provider.one, "did not prefetch resource from file1") - assert_equal("a", will.provider.one, "did not prefetch resource from default") - - assert_equal("bill a c\njill b d\n", prov.target_object(:file1).read, - "Did not write changed resource correctly") - assert_equal("will a d\n", prov.target_object(:default).read, - "Did not write changed default resource correctly") - end - - # Make sure we can correctly prefetch on a target. - def test_prefetch_target - prov = mkprovider - - prov.filetype = :ram - target = :yayness - prov.target_object(target).write "yay b d" - - records = nil - assert_nothing_raised do - records = prov.prefetch_target(:yayness) - end - - # Now make sure we correctly got the hash - record = records.find { |r| r[:name] == "yay" } - assert(record, "Did not get record in prefetch_target") - assert_equal("b", record[:one]) - assert_equal("d", record[:two]) - end - - def test_prefetch_match - prov = mkprovider - - prov.meta_def(:match) do |record, resources| - # Look for matches on :one - if res = resources.find { |name, resource| resource.should(:one).to_s == record[:one].to_s } - res[1] - else - nil - end - end - - prov.filetype = :ram - target = :yayness - prov.target_object(target).write "foo b d" - - resource = mkresource "yay", :target => :yayness, :one => "b" - - assert_nothing_raised do - prov.prefetch("yay" => resource) - end - - # Now make sure we correctly got the hash - mprov = resource.provider - assert_equal("yay", resource[:name]) - assert_equal("b", mprov.one) - assert_equal("d", mprov.two) - end - - # We need to test that we're retrieving files from all three locations: - # from any existing target_objects, from the default file location, and - # from any existing resource instances. - def test_targets - prov = mkprovider - - files = {} - - # Set the default target - default = tempfile - files[:default] = default - prov.default_target = default - - # Create a file object - inmem = tempfile - files[:inmemory] = inmem - prov.target_object(inmem).write("inmem yay ness") - - # Lastly, create a resource with separate is and should values - mtarget = tempfile - files[:resources] = mtarget - resource = mkresource "yay", :target => mtarget - - assert(resource.should(:target), "Did not get a value for target") - - list = nil - - # First run it without the resource - assert_nothing_raised do - list = prov.targets - end - - # Make sure it got the first two, but not the resources file - files.each do |name, file| - if name == :resources - assert(! list.include?(file), "Provider somehow found resource target when no resource was passed") - else - assert(list.include?(file), "Provider did not find #{name} file") - end - end - - # Now list with the resource passed - assert_nothing_raised do - list = prov.targets("yay" => resource) - end - - # And make sure we get all three files - files.each do |name, file| - assert(list.include?(file), "Provider did not find #{name} file when resource was passed") - end - end - - # Make sure that flushing behaves correctly. This is what actually writes - # the data out to disk. - def test_flush - prov = mkprovider - - prov.filetype = :ram - prov.default_target = :yayness - - # Create some resources. - one = mkresource "one", :one => "a", :two => "c", :target => :yayness - two = mkresource "two", :one => "b", :two => "d", :target => :yayness - resources = {"one" => one, "two" => two} - - # Write out a file with different data. - prov.target_object(:yayness).write "one b d\ntwo a c" - - prov.prefetch(resources) - - # Apply and flush the first resource. - assert_nothing_raised do - apply(one) - end - assert_nothing_raised { one.flush } - - # Make sure it didn't clear out our property hash - assert_equal(:a, one.provider.one) - assert_equal(:c, one.provider.two) - - # And make sure it's right on disk - assert(prov.target_object(:yayness).read.include?("one a c"), "Did not write out correct data") - - # Make sure the second resource has not been modified - assert_equal("a", two.provider.one, "Two was flushed early") - assert_equal("c", two.provider.two, "Two was flushed early") - - # And on disk - assert(prov.target_object(:yayness).read.include?("two a c"), "Wrote out other resource") - - # Now fetch the data again and make sure we're still right - assert_nothing_raised { prov.prefetch(resources) } - assert_equal("a", one.provider.one) - assert_equal("a", two.provider.one) - - # Now flush the second resource and make sure it goes well - assert_nothing_raised { apply(two) } - assert_nothing_raised { two.flush } - - # And make sure it didn't clear our hash - assert_equal(:b, two.provider.one) - end - - # Make sure it works even if the file does not currently exist - def test_creating_file - prov = mkprovider - prov.clear - - prov.default_target = :basic - - resource = mkresource "yay", :target => :basic, :one => "a", :two => "c" - - assert_equal(:present, resource.should(:ensure)) - - apply(resource) - - assert_nothing_raised do - resource.flush - end - - assert_equal("yay a c\n", prov.target_object(:basic).read, - "Did not create file") - - # Make a change - resource.provider.one = "b" - - # Flush it - assert_nothing_raised do - resource.flush - end - - # And make sure our resource doesn't appear twice in the file. - assert_equal("yay b c\n", prov.target_object(:basic).read, "Wrote record to file twice") - end - - # Make sure a record can switch targets. - def test_switching_targets - prov = mkprovider - - prov.filetype = :ram - prov.default_target = :first - - # Make three resources, one for each target and one to switch - first = mkresource "first", :target => :first - second = mkresource "second", :target => :second - mover = mkresource "mover", :target => :first - - [first, second, mover].each do |m| - assert_nothing_raised("Could not apply #{m[:name]}") do - apply(m) - end - end - - # Flush. - [first, second, mover].each do |m| - assert_nothing_raised do - m.flush - end - end - - check = proc do |target, name| - assert(prov.target_object(target).read.include?("#{name} a c"), "Did not sync #{name}") - end - # Make sure the data is there - check.call(:first, :first) - check.call(:second, :second) - check.call(:first, :mover) - - # Now change the target for the mover - mover[:target] = :second - - # Apply it - assert_nothing_raised do - apply(mover) - end - - # Flush - assert_nothing_raised do - mover.flush - end - - # Make sure the data is there - check.call(:first, :first) - check.call(:second, :second) - check.call(:second, :mover) - - # And make sure the mover is no longer in the first file - assert(prov.target_object(:first) !~ /mover/, "Mover was not removed from first file") - end - - # Make sure that 'ensure' correctly calls 'sync' on all properties. - def test_ensure - prov = mkprovider - - prov.filetype = :ram - prov.default_target = :first - - # Make two resources, one that starts on disk and one that doesn't - ondisk = mkresource "ondisk", :target => :first - notdisk = mkresource "notdisk", :target => :first - - prov.target_object(:first).write "ondisk a c\n" - prov.prefetch("ondisk" => ondisk, "notdisk" => notdisk) - - - assert_equal( - :present, notdisk.should(:ensure), - - "Did not get default ensure value") - - # Try creating the object - assert_nothing_raised { notdisk.provider.create } - - # Now make sure all of the data is copied over correctly. - notdisk.class.validproperties.each do |property| - assert_equal(notdisk.should(property), notdisk.provider.property_hash[property], - "#{property} was not copied over during creation") - end - - # Flush it to disk and make sure it got copied down - assert_nothing_raised do - notdisk.flush - end - - assert(prov.target_object(:first).read =~ /^notdisk/, - "Did not write out object to disk") - assert(prov.target_object(:first).read =~ /^ondisk/, - "Lost object on disk") - - # Make sure our on-disk resource behaves appropriately. - assert_equal(:present, ondisk.provider.ensure) - - # Now destroy the object - assert_nothing_raised { notdisk.provider.destroy } - - assert_nothing_raised { notdisk.flush } - - # And make sure it's no longer present - assert(prov.target_object(:first).read !~ /^notdisk/, "Did not remove thing from disk") - assert(prov.target_object(:first).read =~ /^ondisk/, "Lost object on disk") - assert_equal(:present, ondisk.provider.ensure) - end - - def test_absent_fields - prov = @type.provide(:record, :parent => Puppet::Provider::ParsedFile) do - record_line :record, :fields => %w{name one two}, - :separator => "\s" - end - cleanup { @type.unprovide(:record) } - - line = prov.parse_line("a d") - - assert_equal("a", line[:name], "field name was not set") - assert_equal(:absent, line[:one], "field one was not set to absent") - - # Now use a different provider with a non-blank "absent" - prov = @type.provide(:cronstyle, :parent => Puppet::Provider::ParsedFile) do - record_line :cronstyle, :fields => %w{name one two}, - :separator => "\s", :absent => "*" - end - cleanup { @type.unprovide(:cronstyle) } - line = prov.parse_line("a * d") - - assert_equal("a", line[:name], "field name was not set") - assert_equal(:absent, line[:one], "field one was not set to absent") - end - - # This test is because in x2puppet I was having problems where multiple - # retrievals somehow destroyed the 'is' values. - def test_value_retrieval - prov = mkprovider - prov.default_target = :yayness - - prov.target_object(:yayness).write "bill a c\njill b d" - - list = @type.instances - - bill = list.find { |r| r[:name] == "bill" } - jill = list.find { |r| r[:name] == "jill" } - assert(bill, "Could not find bill") - assert(jill, "Could not find jill") - - prov = bill.provider - - 4.times do |i| - assert(prov.one, "Did not get a value for 'one' on try #{(i + 1)}") - end - - # First make sure we can retrieve values multiple times from the - # provider - bills_values = nil - assert_nothing_raised do - bills_values = bill.retrieve - end - - assert(bills_values[bill.property(:one)], - "Bill does not have a value for 'one'") - assert(bills_values[bill.property(:one)], - "Bill does not have a value for 'one' on second try") - assert_nothing_raised do - bill.retrieve - end - assert(bills_values[bill.property(:one)], - "bill's value for 'one' disappeared") - end - - # Make sure that creating a new resource finds existing records in memory - def test_initialize_finds_records - prov = mkprovider - prov.default_target = :yayness - - prov.target_object(:yayness).write "bill a c\njill b d" - - prov.prefetch - - # Now make a resource - bill = @type.new :name => "bill" - - assert_equal("a", bill.provider.one, "Record was not found in memory") - end - - # Make sure invalid fields always show up as insync - def test_invalid_fields - - prov = @type.provide( - :test, :parent => Puppet::Provider::ParsedFile, - - :filetype => :ram, :default_target => :yayness) do - record_line :test, :fields => %w{name two} - end - cleanup do @type.unprovide(:test) end - - bill = nil - assert_nothing_raised do - bill = @type.new :name => "bill", - :one => "a", :two => "c" - end - - assert_apply(bill) - - prov.prefetch - current_value = nil - assert_nothing_raised do - current_value = bill.retrieve - end - - assert_events([], bill) - end - - # Make sure we call the prefetch hook at the right place. - def test_prefetch_hook - - prov = @type.provide( - :test, :parent => Puppet::Provider::ParsedFile, - - :filetype => :ram, :default_target => :yayness) do - - def self.prefetch_hook(records) - records - end - - record_line :test, :fields => %w{name two} - end - cleanup do @type.unprovide(:test) end - - target = "target" - - records = [{:target => "nope"}] - targeted = {:target => "target"} - prov.send(:instance_variable_set, "@records", records) - prov.expects(:retrieve).with(target).returns([targeted]) - - prov.expects(:prefetch_hook).with([targeted]).returns([targeted]) - - prov.prefetch_target(target) - end - - # #529 - def test_keep_content_with_target - mkprovider - @provider.filetype = :flat - dpath = tempfile - opath = tempfile - @provider.default_target = dpath - - dtarget = @provider.target_object(dpath) - otarget = @provider.target_object(opath) - - dtarget.write("dname a c\n") - otarget.write("oname b d\n") - - # Now make a resource that targets elsewhat. - res = @type.new(:name => "test", :one => "a", :two => "c", :target => opath) - - assert(res.property(:target), "Target is a parameter, not a property") - - assert_apply(res) - - - assert_equal( - "oname b d\ntest a c\n", otarget.read, - - "did not get correct results in specified target") - end -end - - diff --git a/test/ral/providers/port/parsed.rb b/test/ral/providers/port/parsed.rb deleted file mode 100755 index 062044796..000000000 --- a/test/ral/providers/port/parsed.rb +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' -#require 'puppettest/fileparsing' -#require 'puppet/type/port' -#require 'test/unit' -#require 'facter' -# -#class TestParsedPort < Test::Unit::TestCase -# include PuppetTest -# include PuppetTest::FileParsing -# -# def setup -# super -# @provider = Puppet::Type.type(:port).provider(:parsed) -# @oldfiletype = @provider.filetype -# end -# -# def teardown -# Puppet::Util::FileType.filetype(:ram).clear -# @provider.filetype = @oldfiletype -# @provider.clear -# super -# end -# -# # Generate a line from a hash. The line might include '\n'. -# def genline(hash) -# line = [hash[:name], "#{hash[:number]}/%s"].join("\t\t") -# if hash[:alias] -# line += "\t\t" + hash[:alias].join(" ") -# end -# if hash[:description] -# line += "\t# " + hash[:description] -# end -# -# return hash[:protocols].collect { |p| line % p }.join("\n") -# end -# -# # Parse our sample data and make sure we regenerate it correctly. -# def test_portsparse -# files = fakedata("data/types/port") -# files.each do |file| -# oldtarget = @provider.default_target -# cleanup do -# @provider.default_target = oldtarget -# end -# @provider.default_target = file -# -# assert_nothing_raised("failed to fetch #{file}") { -# @provider.prefetch -# } -# -# hashes = @provider.target_records(file).find_all { |i| i.is_a? Hash } -# assert(hashes.length > 0, "Did not create any hashes") -# dns = hashes.find { |i| i[:name] == "domain" } -# -# assert(dns, "Did not retrieve dns record") -# assert_equal("53", dns[:number], "dns number is wrong") -# -# text = nil -# assert_nothing_raised("failed to generate #{file}") do -# text = @provider.to_file(@provider.target_records(file)) -# end -# -# oldlines = File.readlines(file) -# newlines = text.chomp.split "\n" -# regex = /^(\S+)\s+(\d+)\/(\w+)/ -# oldlines.zip(newlines).each do |old, new| -# if omatch = regex.match(old) -# assert(newmatch = regex.match(new), -# "Lines were not equivalent: %s vs %s" % -# [old.inspect, new.inspect] -# ) -# oldfields = omatch.captures and -# newfields = newmatch.captures -# -# assert_equal(oldfields, newfields, -# "Lines were not equivalent: %s vs %s" % -# [old.inspect, new.inspect] -# ) -# end -# # assert_equal(old.chomp.gsub(/\s+/, ''), -# # new.gsub(/\s+/, ''), -# # "Lines are not equal in #{file}") -# end -# end -# end -# -# # Try parsing the different forms of lines -# def test_parsing -# # Each of the different possible values for each field. -# options = { -# :name => "service", -# :number => "1", -# :alias => [nil, ["null"], %w{null sink}, %w{null sink other}], -# :description => [nil, "my description"], -# :protocols => [%w{tcp}, %w{udp}, %w{tcp udp}] -# } -# -# # Now go through all of the different iterations and make sure we -# # parse them correctly. -# keys = options.keys -# -# name = options[:name] -# number = options[:number] -# options[:alias].each do |al| -# options[:description].each do |desc| -# options[:protocols].each do |proto| -# hash = {:name => name, :number => number, :alias => al, -# :description => desc, :protocols => proto} -# line = genline(hash) -# -# # Try parsing it -# record = nil -# assert_nothing_raised do -# record = @provider.parse_line(line) -# end -# assert(record, "Did not get record returned") -# hash.each do |param, value| -# if value -# assert_equal(value, record[param], -# "did not get #{param} out of '#{line}'") -# end -# end -# -# # Now make sure it generates correctly -# assert_equal(line, @provider.to_line(record), -# "Did not generate #{line} correctly") -# end -# end -# end -# end -# -# # Make sure we correctly join lines by name, so that they're considered -# # a single record. -# def test_lines -# result = nil -# assert_nothing_raised do -# result = @provider.lines( -#"smtp 25/tcp mail -#time 37/tcp timserver -#time 37/udp timserver -#rlp 39/udp resource # resource location -#tacacs 49/tcp # Login Host Protocol (TACACS) -#nameserver 42/tcp name # IEN 116 -#whois 43/tcp nicname -#tacacs 49/udp -#re-mail-ck 50/tcp # Remote Mail Checking Protocol -#domain 53/tcp nameserver # name-domain server -#re-mail-ck 50/udp -#domain 53/udp nameserver" -# ) -# end -# -# assert_equal([ -#"smtp 25/tcp mail", -#"time 37/tcp timserver -#time 37/udp timserver", -#"rlp 39/udp resource # resource location", -#"tacacs 49/tcp # Login Host Protocol (TACACS) -#tacacs 49/udp", -#"nameserver 42/tcp name # IEN 116", -#"whois 43/tcp nicname", -#"re-mail-ck 50/tcp # Remote Mail Checking Protocol -#re-mail-ck 50/udp", -#"domain 53/tcp nameserver # name-domain server -#domain 53/udp nameserver" -#], result) -# -# end -# -# # Make sure we correctly handle port merging. -# def test_port_merge -# fields = [:name, :number, :protocols, :alias, :description] -# base = %w{a 1} -# -# z = proc { |ary| h = {}; fields.zip(ary) { |p,v| h[p] = v if v }; h } -# -# # Make sure our zipper is working -# assert_equal({:name => "a", :number => "1", :protocols => %w{tcp udp}}, -# z.call(["a", "1", %w{tcp udp}]) -# ) -# -# # Here we go through the different options, just testing each key -# # separately. -# { -# # The degenerate case - just two protocols -# [%w{tcp udp}] => [[%w{tcp}], [%w{udp}]], -# -# # one alias -# [%w{tcp udp}, %w{A}] => [[%w{tcp}, %w{A}], [%w{udp}]], -# -# # Other side -# [%w{tcp udp}, %w{A}] => [[%w{tcp}], [%w{udp}], %w{A}], -# -# # Both -# [%w{tcp udp}, %w{A}] => [[%w{tcp}, %w{A}], [%w{udp}], %w{A}], -# -# # Adding aliases -# [%w{tcp udp}, %w{A B}] => [[%w{tcp}, %w{A}], [%w{udp}], %w{B}], -# -# # Merging aliases -# [%w{tcp udp}, %w{A B}] => [[%w{tcp}, %w{A B}], [%w{udp}], %w{B}], -# -# # One description -# [%w{tcp udp}, nil, "desc"] => [[%w{tcp}, nil, "desc"], [%w{udp}] ], -# -# # other side -# [%w{tcp udp}, nil, "desc"] => [[%w{tcp}], [%w{udp}, nil, "desc"] ], -# -# # Conflicting -- first hash wins -# [%w{tcp udp}, nil, "first"] => -# [[%w{tcp}, nil, "first"], [%w{udp}, nil, "desc"] ], -# }.each do |result, hashes| -# assert_equal( -# z.call(base + result), -# @provider.port_merge( -# z.call(base + hashes[0]), -# z.call(base + hashes[1]) -# ), -# "Did not get %s out of %s + %s" % [ -# result.inspect, -# hashes[0].inspect, -# hashes[1].inspect -# ] -# ) -# end -# end -#end - diff --git a/test/ral/providers/provider.rb b/test/ral/providers/provider.rb deleted file mode 100755 index a9f5ad21c..000000000 --- a/test/ral/providers/provider.rb +++ /dev/null @@ -1,529 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'facter' - -class TestProvider < Test::Unit::TestCase - include PuppetTest - - def echo - echo = Puppet::Util.which("echo") - - raise "Could not find 'echo' binary; cannot complete test" unless echo - - echo - end - - def newprovider - # Create our provider - provider = Class.new(Puppet::Provider) do - @name = :fakeprovider - end - provider.initvars - - provider - end - - def setup - super - @type = Puppet::Type.newtype(:provider_test) do - newparam(:name) {} - ensurable - end - cleanup { Puppet::Type.rmtype(:provider_test) } - end - - def test_confine_defaults_to_suitable - - provider = newprovider - assert(provider.suitable?, "Marked unsuitable with no confines") - end - - def test_confine_results - { - {:true => true} => true, - {:true => false} => false, - {:false => false} => true, - {:false => true} => false, - {:operatingsystem => Facter.value(:operatingsystem)} => true, - {:operatingsystem => :yayness} => false, - {:nothing => :yayness} => false, - {:exists => echo} => true, - {:exists => "/this/file/does/not/exist"} => false, - }.each do |hash, result| - provider = newprovider - - # First test :true - hash.each do |test, val| - assert_nothing_raised do - provider.confine test => val - end - end - - assert_equal(result, provider.suitable?, "Failed for #{hash.inspect}") - - provider.initvars - end - end - - def test_multiple_confines_do_not_override - provider = newprovider - - # Make sure multiple confines don't overwrite each other - provider.confine :true => false - assert(! provider.suitable?) - provider.confine :true => true - assert(! provider.suitable?) - end - - def test_one_failed_confine_is_sufficient - - provider = newprovider - - # Make sure we test multiple of them, and that a single false wins - provider.confine :true => true, :false => false - assert(provider.suitable?) - provider.confine :true => false - assert(! provider.suitable?) - end - - # #1197 - the binary should not be - def test_command_checks_for_binaries_each_time - provider = newprovider - - provider.commands :testing => "/no/such/path" - - provider.stubs(:which).returns "/no/such/path" - - provider.command(:testing) - assert_equal("/no/such/path", provider.command(:testing), "Did not return correct binary path") - end - - def test_command - {:echo => "echo", :echo_with_path => echo, :missing => "nosuchcommand", :missing_qualified => "/path/to/nosuchcommand"}.each do |name, command| - provider = newprovider - assert_nothing_raised("Could not define command #{name} with argument #{command} for provider") do - provider.commands(name => command) - end - - if name.to_s =~ /missing/ - assert_nil(provider.command(name), "Somehow got a response for missing commands") - assert(! provider.suitable?, "Provider was considered suitable with missing command") - next # skip, since we don't do any validity checking here. - end - - assert_equal(echo, provider.command(name), "Did not get correct path for echo") - assert(provider.suitable?, "Provider was not considered suitable with 'echo'") - - # Now make sure they both work - inst = provider.new(nil) - [provider, inst].each do |thing| - assert_nothing_raised("Could not call #{command} on #{thing}") do - out = thing.send(name, "some", "text") - assert_equal("some text\n", out) - end - end - - assert(provider.suitable?, "Provider considered unsuitable") - - # Now add an invalid command - assert_nothing_raised do - provider.commands :fake => "nosuchcommanddefinitely" - end - assert(! provider.suitable?, "Provider considered suitable") - - assert_nil(provider.command(:fake), "Got a value for missing command") - assert_raise(Puppet::Error) do - provider.fake - end - - Puppet[:trace] = false - assert_raise(Puppet::DevError) do - provider.command(:nosuchcmd) - end - - # Lastly, verify that we can find our superclass commands - newprov = Class.new(provider) - newprov.initvars - - assert_equal(echo, newprov.command(name)) - end - end - - def test_default? - provider = newprovider - - assert(! provider.default?, "Was considered default with no settings") - - assert_nothing_raised do - provider.defaultfor :operatingsystem => Facter.value(:operatingsystem) - end - - assert(provider.default?, "Was not considered default") - - # Make sure any true value is sufficient. - assert_nothing_raised do - provider.defaultfor :operatingsystem => [ - :yayness, :rahness, - Facter.value(:operatingsystem) - ] - end - - assert(provider.default?, "Was not considered default") - - # Now make sure that a random setting returns false. - assert_nothing_raised do - provider.defaultfor :operatingsystem => :yayness - end - - assert(! provider.default?, "Was considered default") - end - - # Make sure that failed commands get their output in the error. - def test_outputonfailure - provider = newprovider - - dir = tstdir - file = File.join(dir, "mycmd") - sh = Puppet::Util.which("sh") - File.open(file, "w") { |f| - f.puts %{#!#{sh} - echo A Failure >&2 - exit 2 - } - } - File.chmod(0755, file) - - provider.commands :cmd => file - - inst = provider.new(nil) - - assert_raise(Puppet::ExecutionFailure) do - inst.cmd "some", "arguments" - end - - out = nil - begin - inst.cmd "some", "arguments" - rescue Puppet::ExecutionFailure => detail - out = detail.to_s - end - - - assert( - out =~ /A Failure/, - - "Did not receive command output on failure") - - - assert( - out =~ /Execution of/, - - "Did not receive info wrapper on failure") - end - - def test_mk_resource_methods - prov = newprovider - resourcetype = Struct.new(:validproperties, :parameters) - m = resourcetype.new([:prop1, :prop2], [:param1, :param2]) - prov.resource_type = m - - assert_nothing_raised("could not call mk_resource_methods") do - prov.mk_resource_methods - end - - obj = prov.new(nil) - - %w{prop1 prop2 param1 param2}.each do |param| - assert(prov.public_method_defined?(param), "no getter for #{param}") - assert(prov.public_method_defined?(param + "="), "no setter for #{param}") - - - assert_equal( - :absent, obj.send(param), - - "%s did not default to :absent") - val = "testing #{param}" - assert_nothing_raised("Could not call setter for #{param}") do - obj.send(param + "=", val) - end - - assert_equal( - val, obj.send(param), - - "did not get correct value for #{param}") - end - end - - # Make sure optional commands get looked up but don't affect suitability. - def test_optional_commands - type = Puppet::Type.newtype(:optional_commands) {} - - cleanup { Puppet::Type.rmtype(:optional_commands) } - - # Define a provider with mandatory commands - required = type.provide(:required) { - commands :missing => "/no/such/binary/definitely" - } - - # And another with optional commands - optional = type.provide(:optional) { - optional_commands :missing => "/no/such/binary/definitely" - } - - assert(! required.suitable?, "Provider with missing commands considered suitable") - assert_nil(required.command(:missing), "Provider returned non-nil from missing command") - - assert(optional.suitable?, "Provider with optional commands considered unsuitable") - assert_nil(optional.command(:missing), "Provider returned non-nil from missing command") - - assert_raise(Puppet::Error, "Provider did not fail when missing command was called") do - optional.missing - end - end - - # Disabling, since I might not keep this interface - def disabled_test_read_and_each - # Create a new provider - provider = @type.provide(:testing) - - assert_raise(Puppet::DevError, "Did not fail when :read was not overridden") do - provider.read - end - - children = [:one, :two] - provider.meta_def(:read) do - children - end - - result = [] - assert_nothing_raised("could not call 'each' on provider class") do - provider.each { |i| result << i } - end - - assert_equal(children, result, "did not get correct list from each") - - assert_equal(children, provider.collect { |i| i }, "provider does not include enumerable") - end - - def test_source - base = @type.provide(:base) - - assert_equal(:base, base.source, "source did not default correctly") - assert_equal(:base, base.source, "source did not default correctly") - - sub = @type.provide(:sub, :parent => :base) - - assert_equal(:sub, sub.source, "source did not default correctly for sub class") - assert_equal(:sub, sub.source, "source did not default correctly for sub class") - - other = @type.provide(:other, :parent => :base, :source => :base) - - assert_equal(:base, other.source, "source did not override") - assert_equal(:base, other.source, "source did not override") - end - - # Make sure we can initialize with either a resource or a hash, or none at all. - def test_initialize - test = @type.provide(:test) - - inst = @type.new :name => "boo" - prov = nil - assert_nothing_raised("Could not init with a resource") do - prov = test.new(inst) - end - assert_equal(prov.resource, inst, "did not set resource correctly") - assert_equal(inst.name, prov.name, "did not get resource name") - - params = {:name => :one, :ensure => :present} - assert_nothing_raised("Could not init with a hash") do - prov = test.new(params) - end - assert_equal(params, prov.send(:instance_variable_get, "@property_hash"), "did not set resource correctly") - assert_equal(:one, prov.name, "did not get name from hash") - - assert_nothing_raised("Could not init with no argument") do - prov = test.new - end - - assert_raise(Puppet::DevError, "did not fail when no name is present") do - prov.name - end - end -end - -class TestProviderFeatures < Test::Unit::TestCase - include PuppetTest - - def setup - super - @type = Puppet::Type.newtype(:feature_test) do - newparam(:name) {} - ensurable - end - cleanup { Puppet::Type.rmtype(:feature_test) } - - @features = {:numeric => [:one, :two], :alpha => [:a, :b]} - - @features.each do |name, methods| - assert_nothing_raised("Could not define features") do - @type.feature(name, "boo", :methods => methods) - end - end - end - - # Give them the basic run-through. - def test_method_features - @providers = {:numbers => @features[:numeric], :letters => @features[:alpha]} - @providers[:both] = @features[:numeric] + @features[:alpha] - @providers[:mixed] = [:one, :b] - @providers[:neither] = [:something, :else] - - @providers.each do |name, methods| - assert_nothing_raised("Could not create provider #{name}") do - @type.provide(name) do - methods.each do |name| - define_method(name) {} - end - end - end - end - - resource = @type.new(:name => "foo") - {:numbers => [:numeric], :letters => [:alpha], :both => [:numeric, :alpha], :mixed => [], :neither => []}.each do |name, should| - should.sort! { |a,b| a.to_s <=> b.to_s } - provider = @type.provider(name) - assert(provider, "Could not find provider #{name}") - assert_equal(should, provider.features, "Provider #{name} has incorrect features") - - inst = provider.new(resource) - # Make sure the boolean methods work on both the provider and - # instance. - @features.keys.each do |feature| - method = feature.to_s + "?" - assert(inst.respond_to?(method), "No boolean instance method for #{name} on #{feature}") - assert(provider.respond_to?(method), "No boolean class method for #{name} on #{feature}") - - if should.include?(feature) - assert(provider.feature?(feature), "class missing feature? #{feature}") - assert(inst.feature?(feature), "instance missing feature? #{feature}") - assert(provider.send(method), "class missing feature #{feature}") - assert(inst.send(method), "instance missing feature #{feature}") - assert(inst.satisfies?(feature), "instance.satisfy #{feature} returned false") - else - assert(! provider.feature?(feature), "class has feature? #{feature}") - assert(! inst.feature?(feature), "instance has feature? #{feature}") - assert(! provider.send(method), "class has feature #{feature}") - assert(! inst.send(method), "instance has feature #{feature}") - assert(! inst.satisfies?(feature), "instance.satisfy #{feature} returned true") - end - end - - end - - Puppet[:trace] = true - Puppet::Type.loadall - Puppet::Type.eachtype do |type| - assert(type.respond_to?(:feature), "No features method defined for #{type.name}") - end - end - - def test_has_feature - # Define a new feature that has no methods - @type.feature(:nomeths, "desc") - - # Define a provider with nothing - provider = @type.provide(:nothing) {} - - - assert( - provider.respond_to?(:has_features), - - "Provider did not get 'has_features' method added") - - assert( - provider.respond_to?(:has_feature), - - "Provider did not get the 'has_feature' alias method") - - # One with the numeric methods and nothing else - @type.provide(:numbers) do - define_method(:one) {} - define_method(:two) {} - end - - # Another with the numbers and a declaration - @type.provide(:both) do - define_method(:one) {} - define_method(:two) {} - - has_feature :alpha - end - - # And just the declaration - @type.provide(:letters) do - has_feature :alpha - end - - # And a provider that declares it has our methodless feature. - @type.provide(:none) do - has_feature :nomeths - end - - should = {:nothing => [], :both => [:numeric, :alpha], - :letters => [:alpha], :numbers => [:numeric], - :none => [:nomeths]} - - should.each do |name, features| - provider_class = @type.provider(name) - provider = provider_class.new({}) - - assert(provider, "did not get provider named #{name}") - features.sort! { |a,b| a.to_s <=> b.to_s } - assert_equal(features, provider.features, "Got incorrect feature list for provider instance #{name}") - assert_equal(features, provider_class.features, "Got incorrect feature list for provider class #{name}") - features.each do |feat| - assert(provider.feature?(feat), "Provider instance #{name} did not have feature #{feat}") - assert(provider_class.feature?(feat), "Provider class #{name} did not have feature #{feat}") - end - end - end - - def test_supports_parameter? - # Make some parameters for each setting - @type.newparam(:neither) {} - @type.newparam(:some, :required_features => :alpha) - @type.newparam(:both, :required_features => [:alpha, :numeric]) - - # and appropriate providers - nope = @type.provide(:nope) {} - maybe = @type.provide(:maybe) { has_feature(:alpha) } - yep = @type.provide(:yep) { has_features(:alpha, :numeric) } - - # Now make sure our providers answer correctly. - [nope, maybe, yep].each do |prov| - assert(prov.respond_to?(:supports_parameter?), "#{prov.name} does not respond to :supports_parameter?") - case prov.name - when :nope - supported = [:neither] - un = [:some, :both] - when :maybe - supported = [:neither, :some] - un = [:both] - when :yep - supported = [:neither, :some, :both] - un = [] - end - - supported.each do |param| - assert(prov.supports_parameter?(param), "#{param} was not supported by #{prov.name}") - end - un.each do |param| - assert(! prov.supports_parameter?(param), "#{param} was incorrectly supported by #{prov.name}") - end - end - end -end - diff --git a/test/ral/providers/service/base.rb b/test/ral/providers/service/base.rb deleted file mode 100755 index 1b5a63e7d..000000000 --- a/test/ral/providers/service/base.rb +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env ruby -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' - -class TestBaseServiceProvider < Test::Unit::TestCase - include PuppetTest - - def test_base - running = tempfile - - commands = {} - %w{touch rm test}.each do |c| - path = %x{which #{c}}.chomp - if path == "" - $stderr.puts "Cannot find '#{c}'; cannot test base service provider" - return - end - commands[c.to_sym] = path - end - - service = Puppet::Type.type(:service).new( - - :name => "yaytest", :provider => :base, - :start => "#{commands[:touch]} #{running}", - :status => "#{commands[:test]} -f #{running}", - - :stop => "#{commands[:rm]} #{running}" - ) - - provider = service.provider - assert(provider, "did not get base provider") - - assert_nothing_raised do - provider.start - end - assert(FileTest.exists?(running), "start was not called correctly") - assert_nothing_raised do - assert_equal(:running, provider.status, "status was not returned correctly") - end - assert_nothing_raised do - provider.stop - end - assert(! FileTest.exists?(running), "stop was not called correctly") - assert_nothing_raised do - assert_equal(:stopped, provider.status, "status was not returned correctly") - end - end - - # Testing #454 - def test_that_failures_propagate - nope = "/no/such/command" - - service = Puppet::Type.type(:service).new( - - :name => "yaytest", :provider => :base, - :start => nope, - :status => nope, - :stop => nope, - - :restart => nope - ) - - provider = service.provider - assert(provider, "did not get base provider") - - # We can't fail well when status is messed up, because we depend on the return code - # of the command for data. - %w{start stop restart}.each do |command| - assert_raise(Puppet::Error, "did not throw error when #{command} failed") do - provider.send(command) - end - end - end -end - diff --git a/test/ral/providers/sshkey/parsed.rb b/test/ral/providers/sshkey/parsed.rb deleted file mode 100755 index 2a6041406..000000000 --- a/test/ral/providers/sshkey/parsed.rb +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' -require 'puppettest/fileparsing' - -class TestParsedSSHKey < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - def setup - super - @provider = Puppet::Type.type(:sshkey).provider(:parsed) - - @oldfiletype = @provider.filetype - end - - def teardown - Puppet::Util::FileType.filetype(:ram).clear - @provider.filetype = @oldfiletype - @provider.clear - super - end - - def mkkey(name = "host.domain.com") - if defined?(@pcount) - @pcount += 1 - else - @pcount = 1 - end - args = { - :name => name || "/fspuppet#{@pcount}", - :key => "thisismykey#{@pcount}", - :host_aliases => ["host1.domain.com","192.168.0.1"], - :type => "dss", - :ensure => :present - } - - fakeresource = fakeresource(:sshkey, args[:name]) - - key = @provider.new(fakeresource) - args.each do |p,v| - key.send(p.to_s + "=", v) - end - - key - end - - def test_keysparse - fakedata("data/types/sshkey").each { |file| - fakedataparse(file) - } - end - - def test_simplekey - @provider.filetype = :ram - file = @provider.default_target - - key = nil - assert_nothing_raised do - key = mkkey - end - - assert(key, "did not create key") - - assert_nothing_raised do - key.flush - end - - assert(key.host_aliases, "No host_aliases set for key") - - hash = key.property_hash.dup - text = @provider.target_object(file).read - names = [key.name, key.host_aliases].flatten.join(",") - - assert_equal("#{names} #{key.type} #{key.key}\n", text) - - assert_nothing_raised do - @provider.prefetch - end - - hash.each do |p, v| - next unless key.respond_to?(p) - assert_equal(v, key.send(p), "#{p} did not match") - end - - assert(key.name !~ /,/, "Aliases were not split out during parsing") - end - - def test_hooks - result = nil - assert_nothing_raised("Could not call post hook") do - result = @provider.parse_line("one,two type key") - end - assert_equal("one", result[:name], "Did not call post hook") - assert_equal(%w{two}, result[:host_aliases], "Did not call post hook") - - - assert_equal( - "one,two type key", - @provider.to_line(:record_type => :parsed, - :name => "one", - :host_aliases => %w{two}, - :type => "type", - - :key => "key"), - "Did not use pre-hook when generating line" - ) - end -end - diff --git a/test/ral/providers/user.rb b/test/ral/providers/user.rb deleted file mode 100755 index ebf2ab700..000000000 --- a/test/ral/providers/user.rb +++ /dev/null @@ -1,586 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'puppettest/support/utils' - -class TestUserProvider < Test::Unit::TestCase - include PuppetTest::Support::Utils - include PuppetTest::FileTesting - - def setup - super - setme - @@tmpusers = [] - @provider = nil - assert_nothing_raised { - @provider = Puppet::Type.type(:user).defaultprovider - } - - assert(@provider, "Could not find default user provider") - - end - - def teardown - @@tmpusers.each { |user| - remove(user) unless missing?(user) - } - super - end - - case Facter["operatingsystem"].value - when "Darwin" - def missing?(user) - output = %x{nidump -r /users/#{user} / 2>/dev/null}.chomp - - return output == "" - - assert_equal("", output, "User #{user} is present:\n#{output}") - end - - def current?(param, user) - property = Puppet::Type.type(:user).properties.find { |st| - st.name == param - } - - prov = Puppet::Type.type(:user).defaultprovider - output = prov.report(param) - output.each { |hash| - if hash[:name] == user.name - val = hash[param] - if val =~ /^[-0-9]+$/ - return Integer(val) - else - return val - end - end - } - - nil - end - - def remove(user) - system("niutil -destroy / /users/#{user}") - end - else - def missing?(user) - obj = Etc.getpwnam(user) - return false - rescue ArgumentError - return true - end - - def current?(param, user) - property = Puppet::Type.type(:user).properties.find { |st| - st.name == param - } - - assert_nothing_raised { - obj = Etc.getpwnam(user.name) - return obj.send(user.posixmethod(param)) - } - - nil - end - - def remove(user) - system("userdel #{user}") - end - end - - - def eachproperty - Puppet::Type.type(:user).validproperties.each do |property| - yield property - end - end - - def findshell(old = nil) - %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh - /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh - /usr/bin/tcsh}.find { |shell| - if old - FileTest.exists?(shell) and shell != old - else - FileTest.exists?(shell) - end - } - end - - def fakedata(name, param) - case param - when :name; name - when :ensure; :present - when :comment; "Puppet's Testing User #{name}" # use a single quote a la #375 - when :gid; nonrootgroup.gid - when :shell; findshell - when :home; "/home/#{name}" - else - return nil - end - end - - def fakeresource(*args) - resource = super - - # Set boolean methods as necessary. - class << resource - def allowdupe? - self[:allowdupe] - end - def managehome? - self[:managehome] - end - end - resource - end - - def mkuser(name) - fakeresource = fakeresource(:user, name) - user = nil - assert_nothing_raised { - user = @provider.new(fakeresource) - } - assert(user, "Could not create provider user") - - user - end - - def test_list - names = nil - assert_nothing_raised { - names = @provider.listbyname - } - - assert(names.length > 0, "Listed no users") - - # Now try it by object - assert_nothing_raised { - names = @provider.instances - } - assert(names.length > 0, "Listed no users as objects") - - names.each do |obj| - assert_instance_of(@provider, obj) - end - end - - def test_infocollection - fakeresource = fakeresource(:user, @me) - - user = nil - assert_nothing_raised { - user = @provider.new(fakeresource) - } - assert(user, "Could not create user provider") - - Puppet::Type.type(:user).validproperties.each do |property| - next if property == :ensure - # This is mostly in place for the 'password' stuff. - next unless user.class.supports_parameter?(property) and Puppet.features.root? - val = nil - assert_nothing_raised { - val = user.send(property) - } - - - assert( - val != :absent, - - "Property #{property} is missing") - - assert(val, "Did not get value for #{property}") - end - end - - def test_exists - user = mkuser("nosuchuserok") - - - assert( - ! user.exists?, - - "Fake user exists?") - - user = mkuser(@me) - - assert( - user.exists?, - - "I don't exist?") - end - - def attrtest_ensure(user) - old = user.ensure - assert_nothing_raised { - user.delete - } - - assert(missing?(user.name), "User is still present") - assert_nothing_raised { - user.create - } - assert(!missing?(user.name), "User is absent") - assert_nothing_raised { - user.delete - } - - unless old == :absent - user.create - end - end - - def attrtest_comment(user) - old = user.comment - - newname = "Billy O'Neal" # use a single quote, a la #372 - assert_nothing_raised { - user.comment = newname - } - - - assert_equal( - newname, current?(:comment, user), - - "Comment was not changed") - - assert_nothing_raised { - user.comment = old - } - - - assert_equal( - old, current?(:comment, user), - - "Comment was not reverted") - end - - def attrtest_home(user) - old = current?(:home, user) - - assert_nothing_raised { - user.home = "/tmp" - } - - assert_equal("/tmp", current?(:home, user), "Home was not changed") - assert_nothing_raised { - user.home = old - } - - assert_equal(old, current?(:home, user), "Home was not reverted") - end - - def attrtest_shell(user) - old = current?(:shell, user) - - newshell = findshell(old) - - unless newshell - $stderr.puts "Cannot find alternate shell; skipping shell test" - return - end - - assert_nothing_raised { - user.shell = newshell - } - - - assert_equal( - newshell, current?(:shell, user), - - "Shell was not changed") - - assert_nothing_raised { - user.shell = old - } - - assert_equal(old, current?(:shell, user), "Shell was not reverted") - end - - def attrtest_gid(user) - old = current?(:gid, user) - - newgroup = %w{nogroup nobody staff users daemon}.find { |gid| - begin - group = Etc.getgrnam(gid) - rescue ArgumentError => detail - next - end - old != group.gid - } - group = Etc.getgrnam(newgroup) - - unless newgroup - $stderr.puts "Cannot find alternate group; skipping gid test" - return - end - - # Stupid DirectoryServices - if Facter.value(:operatingsystem) == "Darwin" - assert_raise(ArgumentError, "gid allowed a non-integer value") do - user.gid = group.name - end - end - - assert_nothing_raised("Failed to specify group by id") { - user.gid = group.gid - } - - assert_equal(group.gid, current?(:gid,user), "GID was not changed") - - assert_nothing_raised("Failed to change back to old gid") { - user.gid = old - } - end - - def attrtest_uid(user) - old = current?(:uid, user) - - newuid = old - while true - newuid += 1 - - if newuid - old > 1000 - $stderr.puts "Could not find extra test UID" - return - end - begin - newuser = Etc.getpwuid(newuid) - rescue ArgumentError => detail - break - end - end - - assert_nothing_raised("Failed to change user id") { - user.uid = newuid - } - - assert_equal(newuid, current?(:uid, user), "UID was not changed") - - assert_nothing_raised("Failed to change user id") { - user.uid = old - } - assert_equal(old, current?(:uid, user), "UID was not changed back") - end - - def attrtest_groups(user) - Etc.setgrent - max = 0 - while group = Etc.getgrent - max = group.gid if group.gid > max and group.gid < 5000 - end - - groups = [] - main = [] - extra = [] - 5.times do |i| - i += 1 - name = "pptstgr#{i}" - - tmpgroup = Puppet::Type.type(:group).new( - - :name => name, - - :gid => max + i - ) - - groups << tmpgroup - - cleanup do - tmpgroup.provider.delete if tmpgroup.provider.exists? - end - - if i < 3 - main << name - else - extra << name - end - end - - # Create our test groups - assert_apply(*groups) - - # Now add some of them to our user - assert_nothing_raised { - user.resource[:groups] = extra.join(",") - } - - # Some tests to verify that groups work correctly startig from nothing - # Remove our user - user.delete - - # And add it again - user.create - - # Make sure that the group list is added at creation time. - # This is necessary because we don't have default fakedata for groups. - assert(user.groups, "Did not retrieve group list") - - list = user.groups.split(",") - assert_equal(extra.sort, list.sort, "Group list was not set at creation time") - - # Now set to our main list of groups - assert_nothing_raised { - user.groups = main.join(",") - } - - list = user.groups.split(",") - assert_equal(main.sort, list.sort, "Group list is not equal") - end - - if Puppet.features.root? - def test_simpleuser - name = "pptest" - - assert(missing?(name), "User #{name} is present") - - user = mkuser(name) - - eachproperty do |property| - if val = fakedata(user.name, property) - user.resource[property] = val - end - end - - @@tmpusers << name - - assert_nothing_raised { - user.create - } - - assert_equal("Puppet's Testing User pptest", - user.comment, - "Comment was not set") - - assert_nothing_raised { - user.delete - } - - assert(missing?(user.name), "User was not deleted") - end - - def test_alluserproperties - user = nil - name = "pptest" - - assert(missing?(name), "User #{name} is present") - - user = mkuser(name) - - eachproperty do |property| - if val = fakedata(user.name, property) - user.resource[property] = val - end - end - - @@tmpusers << name - - assert_nothing_raised { - user.create - } - assert_equal("Puppet's Testing User pptest", user.comment, - "Comment was not set") - - tests = Puppet::Type.type(:user).validproperties - - just = nil - tests.each { |test| - if self.respond_to?("attrtest_#{test}") - self.send("attrtest_#{test}", user) - else - Puppet.err "Not testing attr #{test} of user" - end - } - - assert_nothing_raised { - user.delete - } - end - - # This is a weird method that shows how annoying the interface between - # types and providers is. Grr. - def test_duplicateIDs - user1 = mkuser("user1") - user1.create - user1.uid = 125 - user2 = mkuser("user2") - user2.resource[:uid] = 125 - - cleanup do - user1.delete - user2.delete - end - - # Not all OSes fail here, so we can't test that it doesn't work with - # it off, only that it does work with it on. - assert_nothing_raised { - user2.resource[:allowdupe] = :true - } - assert_nothing_raised { user2.create } - - assert_equal( - :present, user2.ensure, - - "User did not get created") - end - else - $stderr.puts "Not root; skipping user creation/modification tests" - end - - # Here is where we test individual providers - def test_useradd_flags - useradd = nil - assert_nothing_raised { - useradd = Puppet::Type.type(:user).provider(:useradd) - } - assert(useradd, "Did not retrieve useradd provider") - - user = nil - assert_nothing_raised { - fakeresource = fakeresource(:user, @me) - user = useradd.new(fakeresource) - } - - - assert_equal( - "-d", user.send(:flag, :home), - - "Incorrect home flag") - - - assert_equal( - "-s", user.send(:flag, :shell), - - "Incorrect shell flag") - end - - def test_autogen - provider = nil - user = Puppet::Type.type(:user).new(:name => nonrootuser.name) - provider = user.provider - assert(provider, "did not get provider") - - # Everyone should be able to autogenerate a uid - assert_instance_of(Fixnum, provider.autogen(:uid)) - - # If we're Darwin, then we should get results, but everyone else should - # get nil - darwin = (Facter.value(:operatingsystem) == "Darwin") - - should = { - :comment => user[:name].capitalize, - :home => "/var/empty", - :shell => "/usr/bin/false" - } - - should.each do |param, value| - if darwin - assert_equal(value, provider.autogen(param), "did not autogen #{param} for darwin correctly") - else - assert_nil(provider.autogen(param), "autogenned #{param} for non-darwin os") - end - end - end -end - diff --git a/test/ral/providers/user/useradd.rb b/test/ral/providers/user/useradd.rb deleted file mode 100755 index 6350ec6dc..000000000 --- a/test/ral/providers/user/useradd.rb +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'mocha' - -class UserAddProviderTest < PuppetTest::TestCase - confine "useradd user provider missing" => - Puppet::Type.type(:user).provider(:useradd).suitable? - - def setup - super - @type = Puppet::Type.type(:user) - @provider = Puppet::Type.type(:user).provider(:useradd) - @home = tempfile - @vals = {:name => 'faff', - :provider => :useradd, - :ensure => :present, - :uid => 5000, - :gid => 5000, - :home => @home, - :comment => "yayness", - :groups => %w{one two} - } - end - - def setup_user - @user = @type.new(@vals) - - @vals.each do |name, val| - next unless @user.class.validproperty?(name) - end - @user - end - - def test_features - [:manages_homedir].each do |feature| - - assert( - @provider.feature?(feature), - - "useradd provider is missing #{feature}") - end - end - - def test_create - user = setup_user - - @vals.each do |name, val| - next unless user.class.validproperty?(name) - end - - user.expects(:allowdupe?).returns(false) - user.expects(:managehome?).returns(false) - - user.provider.expects(:execute).with do |params| - command = params.shift - assert_equal(@provider.command(:add), command, - "Got incorrect command") - - if %w{Fedora RedHat}.include?(Facter.value(:operatingsystem)) - assert(params.include?("-M"), "Did not disable homedir creation on red hat") - params.delete("-M") - end - - options = {} - options[params.shift] = params.shift while params.length > 0 - - @vals[:groups] = @vals[:groups].join(",") - - flags = {:home => "-d", :groups => "-G", :gid => "-g", - :uid => "-u", :comment => "-c"} - - flags.each do |param, flag| - assert_equal(@vals[param], options[flag], "Got incorrect value for #{param}") - end - - true - end - - user.provider.create - end - - # Make sure we add the right flags when managing home - def test_managehome - @vals[:managehome] = true - setup_user - - - assert( - @user.provider.respond_to?(:manages_homedir?), - - "provider did not get managehome test set") - - assert(@user.managehome?, "provider did not get managehome") - - # First run - @user.expects(:managehome?).returns(true) - - @user.provider.expects(:execute).with do |params| - assert_equal(params[0], @provider.command(:add), "useradd was not called") - assert(params.include?("-m"), "Did not add -m when managehome was in affect") - assert(! params.include?("-M"), "Added -M when managehome was in affect") - - true - end - - @user.provider.create - - # Start again, this time with manages_home off - @vals[:managehome] = false - setup_user - - # First run - @user.expects(:managehome?).returns(false) - - @user.provider.expects(:execute).with do |params| - assert_equal(params[0], @provider.command(:add), "useradd was not called") - assert(params.include?("-M"), "Did not add -M on Red Hat") if %w{Fedora RedHat}.include?(Facter.value(:operatingsystem)) - assert(! params.include?("-m"), "Added -m when managehome was disabled") - - true - end - - @user.provider.create - end - - def test_allowdupe - @vals[:allowdupe] = true - setup_user - - - assert( - @user.provider.respond_to?(:allows_duplicates?), - - "provider did not get allowdupe test set") - - assert(@user.allowdupe?, "provider did not get allowdupe") - - # First run - @user.expects(:allowdupe?).returns(true) - - @user.provider.expects(:execute).with do |params| - assert_equal(params[0], @provider.command(:add), "useradd was not called") - assert(params.include?("-o"), "Did not add -o when allowdupe was in affect") - - true - end - - @user.provider.create - - # Start again, this time with manages_home off - @vals[:allowdupe] = false - setup_user - - # First run - @user.expects(:allowdupe?).returns(false) - - @user.provider.expects(:execute).with do |params| - assert_equal(params[0], @provider.command(:add), "useradd was not called") - assert(! params.include?("-o"), "Added -o when allowdupe was disabled") - - true - end - - @user.provider.create - end - - def test_manages_password - return unless @provider.feature?(:manages_passwords) - @vals[:password] = "somethingorother" - setup_user - - @user.provider.expects(:execute).with do |params| - assert_equal(params[0], @provider.command(:add), "useradd was not called") - params.shift - options = {} - params.each_with_index do |p, i| - if p =~ /^-/ and p != "-M" - options[p] = params[i + 1] - end - end - assert_equal(options["-p"], @vals[:password], "Did not set password in useradd call") - true - end - - @user.provider.create - - # Now mark the user made, and make sure the right command is called - setup_user - @vals[:password] = "somethingelse" - - @user.provider.expects(:execute).with do |params| - assert_equal(params[0], @provider.command(:modify), "usermod was not called") - - options = {} - params.each_with_index do |p, i| - if p =~ /^-/ and p != "-M" - options[p] = params[i + 1] - end - end - - assert_equal( - options["-p"], @vals[:password], - - "Did not set password in useradd call") - true - end - - @user.provider.password = @vals[:password] - end - -end - -class UserRootAddProviderTest < PuppetTest::TestCase - confine "useradd user provider missing" => Puppet::Type.type(:user).provider(:useradd).suitable? - confine "useradd does not manage passwords" => Puppet::Type.type(:user).provider(:useradd).manages_passwords? - confine "not running as root" => (Process.uid == 0) - - def test_password - user = Puppet::Type.type(:user).new(:name => "root", :check => [:password], :provider => :useradd) - - provider = user.provider - - assert_nothing_raised("Could not check password") do - pass = provider.password - assert(pass, "Did not get password for root") - assert(pass!= "x", "Password was retrieved from /etc/passwd instead of /etc/shadow") - end - end -end - - diff --git a/test/ral/type/cron.rb b/test/ral/type/cron.rb deleted file mode 100755 index ae280e04f..000000000 --- a/test/ral/type/cron.rb +++ /dev/null @@ -1,505 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' - -# Test cron job creation, modification, and destruction - -class TestCron < Test::Unit::TestCase - include PuppetTest - - def setup - super - - setme - - @crontype = Puppet::Type.type(:cron) - @provider = @crontype.defaultprovider - if @provider.respond_to?(:filetype=) - @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) - end - @crontype = Puppet::Type.type(:cron) - end - - def teardown - super - @crontype.defaultprovider = nil - end - - def eachprovider - @crontype.suitableprovider.each do |provider| - yield provider - end - end - - # Back up the user's existing cron tab if they have one. - def cronback - tab = nil - assert_nothing_raised { - tab = Puppet::Type.type(:cron).filetype.read(@me) - } - - @currenttab = $CHILD_STATUS == 0 ? tab : nil - end - - # Restore the cron tab to its original form. - def cronrestore - assert_nothing_raised { - if @currenttab - @crontype.filetype.new(@me).write(@currenttab) - else - @crontype.filetype.new(@me).remove - end - } - end - - # Create a cron job with all fields filled in. - def mkcron(name, addargs = true) - cron = nil - command = "date > #{tmpdir()}/crontest#{name}" - args = nil - if addargs - args = { - :command => command, - :name => name, - :user => @me, - :minute => rand(59), - :month => "1", - :monthday => "1", - :hour => "1" - } - else - args = {:command => command, :name => name} - end - assert_nothing_raised { - cron = @crontype.new(args) - } - - cron - end - - # Run the cron through its paces -- install it then remove it. - def cyclecron(cron) - obj = Puppet::Type::Cron.cronobj(@me) - - text = obj.read - name = cron.name - comp = mk_catalog(name, cron) - - assert_events([:cron_created], comp) - cron.provider.class.prefetch - currentvalue = cron.retrieve - - assert(cron.insync?(currentvalue), "Cron is not in sync") - - assert_events([], comp) - - curtext = obj.read - text.split("\n").each do |line| - assert(curtext.include?(line), "Missing '#{line}'") - end - obj = Puppet::Type::Cron.cronobj(@me) - - cron[:ensure] = :absent - - assert_events([:cron_removed], comp) - - cron.provider.class.prefetch - currentvalue = cron.retrieve - - assert(cron.insync?(currentvalue), "Cron is not in sync") - assert_events([], comp) - end - - # Test that a cron job with spaces at the end doesn't get rewritten - def test_trailingspaces - eachprovider do |provider| - cron = nil - # make the cron - name = "yaytest" - command = "date > /dev/null " - assert_nothing_raised { - - cron = @crontype.new( - - :name => name, - :command => "date > /dev/null ", - :month => "May", - - :user => @me - ) - } - property = cron.send(:property, :command) - cron.provider.command = command - cron.provider.ensure = :present - cron.provider.user = @me - cron.provider.month = ["4"] - cron.provider.class.prefetch - currentvalue = cron.retrieve - assert(cron.parameter(:command).insync?(currentvalue[:command]), "Property :command is not considered in sync with value #{currentvalue[:command]}") - end - end - - def test_makeandretrievecron - %w{storeandretrieve a-name another-name more_naming SomeName}.each do |name| - cron = mkcron(name) - catalog = mk_catalog(name, cron) - trans = assert_events([:cron_created], catalog, name) - - cron.provider.class.prefetch - cron = nil - - assert(cron = catalog.resource(:cron, name), "Could not retrieve named cron") - assert_instance_of(Puppet::Type.type(:cron), cron) - end - end - - # Do input validation testing on all of the parameters. - def test_arguments - values = { - :monthday => { - :valid => [ 1, 13, "1" ], - :invalid => [ -1, 0, 32 ] - }, - :weekday => { - :valid => [ 0, 3, 6, "1", "tue", "wed", - "Wed", "MOnday", "SaTurday" ], - :invalid => [ -1, 8, "13", "tues", "teusday", "thurs" ] - }, - :hour => { - :valid => [ 0, 21, 23 ], - :invalid => [ -1, 24 ] - }, - :minute => { - :valid => [ 0, 34, 59 ], - :invalid => [ -1, 60 ] - }, - :month => { - :valid => [ 1, 11, 12, "mar", "March", "apr", "October", "DeCeMbEr" ], - :invalid => [ -1, 0, 13, "marc", "sept" ] - } - } - - cron = mkcron("valtesting") - values.each { |param, hash| - # We have to test the valid ones first, because otherwise the - # property will fail to create at all. - [:valid, :invalid].each { |type| - hash[type].each { |value| - case type - when :valid - assert_nothing_raised { - cron[param] = value - } - - assert_equal([value.to_s], cron.should(param), "Cron value was not set correctly") if value.is_a?(Integer) - when :invalid - assert_raise(Puppet::Error, "#{value} is incorrectly a valid #{param}") { - cron[param] = value - } - end - - if value.is_a?(Integer) - value = value.to_s - redo - end - } - } - } - end - - # Verify that comma-separated numbers are not resulting in rewrites - def test_comma_separated_vals_work - eachprovider do |provider| - cron = nil - assert_nothing_raised { - - cron = @crontype.new( - - :command => "/bin/date > /dev/null", - :minute => [0, 30], - :name => "crontest", - - :provider => provider.name - ) - } - - - cron.provider.ensure = :present - cron.provider.command = '/bin/date > /dev/null' - cron.provider.minute = %w{0 30} - cron.provider.class.prefetch - currentvalue = cron.retrieve - - currentvalue.each do |name, value| - # We're only interested in comparing minutes. - next unless name.to_s == "minute" - assert(cron.parameter(name).insync?(value), "Property #{name} is not considered in sync with value #{value.inspect}") - end - end - end - - def test_fieldremoval - cron = nil - assert_nothing_raised { - - cron = @crontype.new( - - :command => "/bin/date > /dev/null", - :minute => [0, 30], - :name => "crontest", - - :provider => :crontab - ) - } - - assert_events([:cron_created], cron) - cron.provider.class.prefetch - - cron[:minute] = :absent - assert_events([:minute_changed], cron) - - current_values = nil - assert_nothing_raised { - cron.provider.class.prefetch - current_values = cron.retrieve - } - assert_equal(:absent, current_values[cron.property(:minute)]) - end - - def test_listing - # Make a crontab cron for testing - provider = @crontype.provider(:crontab) - return unless provider.suitable? - - ft = provider.filetype - provider.filetype = :ram - cleanup { provider.filetype = ft } - - setme - - cron = @crontype.new( - :name => "testing", - :minute => [0, 30], - :command => "/bin/testing", - - :user => @me - ) - # Write it to our file - assert_apply(cron) - - crons = [] - assert_nothing_raised { - @crontype.instances.each do |cron| - crons << cron - end - } - - crons.each do |cron| - assert_instance_of(@crontype, cron, "Did not receive a real cron object") - - assert_instance_of( - String, cron.value(:user), - - "Cron user is not a string") - end - end - - def verify_failonnouser - assert_raise(Puppet::Error) do - @crontype.retrieve("nosuchuser") - end - end - - def test_divisionnumbers - cron = mkcron("divtest") - cron[:minute] = "*/5" - - assert_apply(cron) - - cron.provider.class.prefetch - currentvalue = cron.retrieve - - assert_equal(["*/5"], currentvalue[cron.property(:minute)]) - end - - def test_ranges - cron = mkcron("rangetest") - cron[:minute] = "2-4" - - assert_apply(cron) - - current_values = nil - assert_nothing_raised { - cron.provider.class.prefetch - current_values = cron.retrieve - } - - assert_equal(["2-4"], current_values[cron.property(:minute)]) - end - - - def provider_set(cron, param, value) - unless param =~ /=$/ - param = "#{param}=" - end - - cron.provider.send(param, value) - end - - def test_value - cron = mkcron("valuetesting", false) - - # First, test the normal properties - [:minute, :hour, :month].each do |param| - cron.newattr(param) - property = cron.property(param) - - assert(property, "Did not get #{param} property") - - assert_nothing_raised { - # property.is = :absent - provider_set(cron, param, :absent) - } - - val = "*" - assert_equal(val, cron.value(param)) - - # Make sure arrays work, too - provider_set(cron, param, ["1"]) - assert_equal(%w{1}, cron.value(param)) - - # Make sure values get comma-joined - provider_set(cron, param, %w{2 3}) - assert_equal(%w{2 3}, cron.value(param)) - - # Make sure "should" values work, too - cron[param] = "4" - assert_equal(%w{4}, cron.value(param)) - - cron[param] = ["4"] - assert_equal(%w{4}, cron.value(param)) - - cron[param] = ["4", "5"] - assert_equal(%w{4 5}, cron.value(param)) - - provider_set(cron, param, :absent) - assert_equal(%w{4 5}, cron.value(param)) - end - - Puppet[:trace] = false - - # Now make sure that :command works correctly - cron.delete(:command) - cron.newattr(:command) - property = cron.property(:command) - - assert_nothing_raised { - provider_set(cron, :command, :absent) - } - - param = :command - # Make sure arrays work, too - provider_set(cron, param, ["/bin/echo"]) - assert_equal("/bin/echo", cron.value(param)) - - # Make sure values are not comma-joined - provider_set(cron, param, %w{/bin/echo /bin/test}) - assert_equal("/bin/echo", cron.value(param)) - - # Make sure "should" values work, too - cron[param] = "/bin/echo" - assert_equal("/bin/echo", cron.value(param)) - - cron[param] = ["/bin/echo"] - assert_equal("/bin/echo", cron.value(param)) - - cron[param] = %w{/bin/echo /bin/test} - assert_equal("/bin/echo", cron.value(param)) - - provider_set(cron, param, :absent) - assert_equal("/bin/echo", cron.value(param)) - end - - def test_multiple_users - crons = [] - users = ["root", nonrootuser.name] - users.each do |user| - - cron = Puppet::Type.type(:cron).new( - - :name => "testcron-#{user}", - :user => user, - :command => "/bin/echo", - - :minute => [0,30] - ) - crons << cron - - assert_equal(cron.should(:user), cron.should(:target), - "Target was not set correctly for #{user}") - end - provider = crons[0].provider.class - - assert_apply(*crons) - - users.each do |user| - users.each do |other| - next if user == other - text = provider.target_object(other).read - - - assert( - text !~ /testcron-#{user}/, - - "#{user}'s cron job is in #{other}'s tab") - end - end - end - - # Make sure the user stuff defaults correctly. - def test_default_user - crontab = @crontype.provider(:crontab) - if crontab.suitable? - - inst = @crontype.new( - - :name => "something", :command => "/some/thing", - - :provider => :crontab) - assert_equal(Etc.getpwuid(Process.uid).name, inst.should(:user), "user did not default to current user with crontab") - assert_equal(Etc.getpwuid(Process.uid).name, inst.should(:target), "target did not default to current user with crontab") - - # Now make a new cron with a user, and make sure it gets copied - # over - - inst = @crontype.new( - :name => "yay", :command => "/some/thing", - - :user => "bin", :provider => :crontab) - - assert_equal( - "bin", inst.should(:target), - - "target did not default to user with crontab") - end - end - - # #705 - make sure extra spaces don't screw things up - def test_spaces_in_command - string = "echo multiple spaces" - cron = @crontype.new(:name => "space testing", :command => string) - assert_apply(cron) - - cron = @crontype.new(:name => "space testing", :command => string) - - # Now make sure that it's correctly in sync - cron.provider.class.prefetch("testing" => cron) - properties = cron.retrieve - assert_equal(string, properties[:command], "Cron did not pick up extra spaces in command") - assert(cron.parameter(:command).insync?(properties[:command]), "Command changed with multiple spaces") - end -end - - diff --git a/test/ral/type/exec.rb b/test/ral/type/exec.rb deleted file mode 100755 index e610c76e7..000000000 --- a/test/ral/type/exec.rb +++ /dev/null @@ -1,727 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' - -class TestExec < Test::Unit::TestCase - include PuppetTest - def test_numvsstring - [0, "0"].each { |val| - command = nil - output = nil - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - - :command => "/bin/echo", - - :returns => val - ) - } - assert_events([:executed_command], command) - } - end - - def test_path_or_qualified - command = nil - output = nil - assert_raise(Puppet::Error) { - command = Puppet::Type.type(:exec).new( - :command => "echo" - ) - } - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - :command => "echo", - :path => "/usr/bin:/bin:/usr/sbin:/sbin" - ) - } - assert_nothing_raised { - command = Puppet::Type.type(:exec).new( - :command => "/bin/echo" - ) - } - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - :command => "/bin/echo", - :path => "/usr/bin:/bin:/usr/sbin:/sbin" - ) - } - end - - def test_nonzero_returns - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - :command => "mkdir /this/directory/does/not/exist", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :returns => 1 - ) - } - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - :command => "touch /etc", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :returns => 1 - ) - } - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - :command => "thiscommanddoesnotexist", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :returns => 127 - ) - } - end - - def test_cwdsettings - command = nil - dir = "/tmp" - wd = Dir.chdir(dir) { - Dir.getwd - } - assert_nothing_raised { - - command = Puppet::Type.type(:exec).new( - :command => "pwd", - :cwd => dir, - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :returns => 0 - ) - } - assert_events([:executed_command], command) - assert_equal(wd,command.output.chomp) - end - - def test_refreshonly_functional - file = nil - cmd = nil - tmpfile = tempfile - @@tmpfiles.push tmpfile - trans = nil - - file = Puppet::Type.type(:file).new( - :path => tmpfile, - :content => "yay" - ) - # Get the file in sync - assert_apply(file) - - # Now make an exec - maker = tempfile - assert_nothing_raised { - cmd = Puppet::Type.type(:exec).new( - :command => "touch #{maker}", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :subscribe => file, - :refreshonly => true - ) - } - - assert(cmd, "did not make exec") - - assert_nothing_raised do - assert(! cmd.check_all_attributes, "Check passed when refreshonly is set") - end - - assert_events([], file, cmd) - assert(! FileTest.exists?(maker), "made file without refreshing") - - # Now change our content, so we throw a refresh - file[:content] = "yayness" - assert_events([:content_changed], file, cmd) - assert(FileTest.exists?(maker), "file was not made in refresh") - end - - def test_refreshonly - cmd = true - assert_nothing_raised { - cmd = Puppet::Type.type(:exec).new( - :command => "pwd", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :refreshonly => true - ) - } - - # Checks should always fail when refreshonly is enabled - assert(!cmd.check_all_attributes, "Check passed with refreshonly true") - - # Now make sure it passes if we pass in "true" - assert(cmd.check_all_attributes(true), "Check failed with refreshonly true while refreshing") - - # Now set it to false - cmd[:refreshonly] = false - assert(cmd.check_all_attributes, "Check failed with refreshonly false") - end - - def test_creates - file = tempfile - exec = nil - assert(! FileTest.exists?(file), "File already exists") - assert_nothing_raised { - - exec = Puppet::Type.type(:exec).new( - :command => "touch #{file}", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - :creates => file - ) - } - - comp = mk_catalog("createstest", exec) - assert_events([:executed_command], comp, "creates") - assert_events([], comp, "creates") - end - - # Verify that we can download the file that we're going to execute. - def test_retrievethenmkexe - exe = tempfile - oexe = tempfile - sh = %x{which sh} - File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" } - - file = Puppet::Type.type(:file).new( - :path => oexe, - :source => exe, - :mode => 0755 - ) - - exec = Puppet::Type.type(:exec).new( - :command => oexe, - :require => Puppet::Resource.new(:file, oexe) - ) - - comp = mk_catalog("Testing", file, exec) - - assert_events([:file_created, :executed_command], comp) - end - - # Verify that we auto-require any managed scripts. - def test_autorequire_files - exe = tempfile - oexe = tempfile - sh = %x{which sh} - File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" } - - - file = Puppet::Type.type(:file).new( - :path => oexe, - :source => exe, - :mode => 755 - ) - - basedir = File.dirname(oexe) - - baseobj = Puppet::Type.type(:file).new( - :path => basedir, - :source => exe, - :mode => 755 - ) - - - ofile = Puppet::Type.type(:file).new( - :path => exe, - :mode => 755 - ) - - - exec = Puppet::Type.type(:exec).new( - :command => oexe, - :path => ENV["PATH"], - :cwd => basedir - ) - - cat = Puppet::Type.type(:exec).new( - :command => "cat #{exe} #{oexe}", - :path => ENV["PATH"] - ) - - catalog = mk_catalog(file, baseobj, ofile, exec, cat) - - rels = nil - assert_nothing_raised do - rels = exec.autorequire - end - - # Verify we get the script itself - assert(rels.detect { |r| r.source == file }, "Exec did not autorequire its command") - - # Verify we catch the cwd - assert(rels.detect { |r| r.source == baseobj }, "Exec did not autorequire its cwd") - - # Verify we don't require ourselves - assert(! rels.detect { |r| r.source == ofile }, "Exec incorrectly required mentioned file") - - # We not longer autorequire inline files - assert_nothing_raised do - rels = cat.autorequire - end - assert(! rels.detect { |r| r.source == ofile }, "Exec required second inline file") - assert(! rels.detect { |r| r.source == file }, "Exec required inline file") - end - - def test_ifonly - afile = tempfile - bfile = tempfile - - exec = nil - assert_nothing_raised { - - exec = Puppet::Type.type(:exec).new( - :command => "touch #{bfile}", - :onlyif => "test -f #{afile}", - :path => ENV['PATH'] - ) - } - - assert_events([], exec) - system("touch #{afile}") - assert_events([:executed_command], exec) - assert_events([:executed_command], exec) - system("rm #{afile}") - assert_events([], exec) - end - - def test_unless - afile = tempfile - bfile = tempfile - - exec = nil - assert_nothing_raised { - exec = Puppet::Type.type(:exec).new( - :command => "touch #{bfile}", - :unless => "test -f #{afile}", - :path => ENV['PATH'] - ) - } - comp = mk_catalog(exec) - - assert_events([:executed_command], comp) - assert_events([:executed_command], comp) - system("touch #{afile}") - assert_events([], comp) - assert_events([], comp) - system("rm #{afile}") - assert_events([:executed_command], comp) - assert_events([:executed_command], comp) - end - - if Puppet.features.root? - # Verify that we can execute commands as a special user - def mknverify(file, user, group = nil, id = true) - File.umask(0022) - - args = { - :command => "touch #{file}", - :path => "/usr/bin:/bin:/usr/sbin:/sbin", - } - - if user - #Puppet.warning "Using user #{user.name}" - if id - # convert to a string, because that's what the object expects - args[:user] = user.uid.to_s - else - args[:user] = user.name - end - end - - if group - #Puppet.warning "Using group #{group.name}" - if id - args[:group] = group.gid.to_s - else - args[:group] = group.name - end - end - exec = nil - assert_nothing_raised { - exec = Puppet::Type.type(:exec).new(args) - } - - comp = mk_catalog("usertest", exec) - assert_events([:executed_command], comp, "usertest") - - assert(FileTest.exists?(file), "File does not exist") - assert_equal(user.uid, File.stat(file).uid, "File UIDs do not match") if user - - # We can't actually test group ownership, unfortunately, because - # behaviour changes wildlly based on platform. - Puppet::Type.allclear - end - - def test_userngroup - file = tempfile - [ - [nonrootuser], # just user, by name - [nonrootuser, nil, true], # user, by uid - [nil, nonrootgroup], # just group - [nil, nonrootgroup, true], # just group, by id - [nonrootuser, nonrootgroup], # user and group, by name - [nonrootuser, nonrootgroup, true], # user and group, by id - ].each { |ary| - mknverify(file, *ary) { - } - } - end - end - - def test_logoutput - exec = nil - assert_nothing_raised { - exec = Puppet::Type.type(:exec).new( - :title => "logoutputesting", - :path => "/usr/bin:/bin", - :command => "echo logoutput is false" - ) - } - - assert_equal(:on_failure, exec[:logoutput]) - assert_apply(exec) - - assert_nothing_raised { - exec[:command] = "echo logoutput is true" - exec[:logoutput] = true - } - - assert_equal(:true, exec[:logoutput]) - assert_apply(exec) - - assert_nothing_raised { - exec[:command] = "echo logoutput is false" - exec[:logoutput] = false - } - - assert_equal(:false, exec[:logoutput]) - assert_apply(exec) - - assert_nothing_raised { - exec[:command] = "echo logoutput is on_failure" - exec[:logoutput] = "on_failure" - } - - assert_equal(:on_failure, exec[:logoutput]) - assert_apply(exec) - end - - def test_execthenfile - exec = nil - file = nil - basedir = tempfile - path = File.join(basedir, "subfile") - assert_nothing_raised { - - exec = Puppet::Type.type(:exec).new( - :title => "mkdir", - :path => "/usr/bin:/bin", - :creates => basedir, - :command => "mkdir #{basedir}; touch #{path}" - ) - } - - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - :path => basedir, - :recurse => true, - :mode => "755", - :require => Puppet::Resource.new("exec", "mkdir") - ) - } - - comp = mk_catalog(file, exec) - comp.finalize - assert_events([:executed_command, :mode_changed], comp) - - assert(FileTest.exists?(path), "Exec ran first") - assert(File.stat(path).mode & 007777 == 0755) - end - - # Make sure all checks need to be fully qualified. - def test_falsevals - exec = nil - assert_nothing_raised do - exec = Puppet::Type.type(:exec).new( - :command => "/bin/touch yayness" - ) - end - - Puppet::Type.type(:exec).checks.each do |check| - klass = Puppet::Type.type(:exec).paramclass(check) - next if klass.value_collection.values.include? :false - assert_raise(Puppet::Error, "Check '#{check}' did not fail on false") do - exec[check] = false - end - end - end - - def test_createcwdandexe - exec1 = exec2 = nil - dir = tempfile - file = tempfile - - assert_nothing_raised { - exec1 = Puppet::Type.type(:exec).new( - :title => "one", - :path => ENV["PATH"], - :command => "mkdir #{dir}" - ) - } - - assert_nothing_raised("Could not create exec w/out existing cwd") { - - exec2 = Puppet::Type.type(:exec).new( - :title => "two", - :path => ENV["PATH"], - :command => "touch #{file}", - :cwd => dir - ) - } - - # Throw a check in there with our cwd and make sure it works - assert_nothing_raised("Could not check with a missing cwd") do - exec2[:unless] = "test -f /this/file/does/not/exist" - exec2.retrieve - end - - assert_raise(Puppet::Error) do - exec2.property(:returns).sync - end - - assert_nothing_raised do - exec2[:require] = exec1 - end - - assert_apply(exec1, exec2) - - assert(FileTest.exists?(file)) - end - - def test_checkarrays - exec = nil - file = tempfile - - test = "test -f #{file}" - - assert_nothing_raised { - exec = Puppet::Type.type(:exec).new( - :path => ENV["PATH"], - :command => "touch #{file}" - ) - } - - assert_nothing_raised { - exec[:unless] = test - } - - assert_nothing_raised { - assert(exec.check_all_attributes, "Check did not pass") - } - - assert_nothing_raised { - exec[:unless] = [test, test] - } - - - assert_nothing_raised { - exec.finish - } - - assert_nothing_raised { - assert(exec.check_all_attributes, "Check did not pass") - } - - assert_apply(exec) - - assert_nothing_raised { - assert(! exec.check_all_attributes, "Check passed") - } - end - - def test_missing_checks_cause_failures - # Solaris's sh exits with 1 here instead of 127 - return if Facter.value(:operatingsystem) == "Solaris" - - exec = Puppet::Type.type(:exec).new( - :command => "echo true", - :path => ENV["PATH"], - :onlyif => "/bin/nosuchthingexists" - ) - - assert_raise(ArgumentError, "Missing command did not raise error") { - exec.provider.run("/bin/nosuchthingexists") - } - end - - def test_environmentparam - - exec = Puppet::Type.newexec( - :command => "echo $environmenttest", - :path => ENV["PATH"], - :environment => "environmenttest=yayness" - ) - - assert(exec, "Could not make exec") - - output = status = nil - assert_nothing_raised { - output, status = exec.provider.run("echo $environmenttest") - } - - assert_equal("yayness\n", output) - - # Now check whether we can do multiline settings - assert_nothing_raised do - exec[:environment] = "environmenttest=a list of things -and stuff" - end - - output = status = nil - assert_nothing_raised { - output, status = exec.provider.run('echo "$environmenttest"') - } - assert_equal("a list of things\nand stuff\n", output) - - # Now test arrays - assert_nothing_raised do - exec[:environment] = ["funtest=A", "yaytest=B"] - end - - output = status = nil - assert_nothing_raised { - output, status = exec.provider.run('echo "$funtest" "$yaytest"') - } - assert_equal("A B\n", output) - end - - # Testing #470 - def test_run_as_created_user - exec = nil - if Process.uid == 0 - user = "nosuchuser" - assert_nothing_raised("Could not create exec with non-existent user") do - exec = Puppet::Type.type(:exec).new( - :command => "/bin/echo yay", - :user => user - ) - end - end - - # Now try the group - group = "nosuchgroup" - assert_nothing_raised("Could not create exec with non-existent user") do - - exec = Puppet::Type.type(:exec).new( - :command => "/bin/echo yay", - :group => group - ) - end - end - - # make sure paths work both as arrays and strings - def test_paths_as_arrays - path = %w{/usr/bin /usr/sbin /sbin} - exec = nil - assert_nothing_raised("Could not use an array for the path") do - exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => path) - end - assert_equal(path, exec[:path], "array-based path did not match") - assert_nothing_raised("Could not use a string for the path") do - exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => path.join(":")) - end - assert_equal(path, exec[:path], "string-based path did not match") - assert_nothing_raised("Could not use a colon-separated strings in an array for the path") do - exec = Puppet::Type.type(:exec).new(:command => "echo yay", :path => ["/usr/bin", "/usr/sbin:/sbin"]) - end - assert_equal(path, exec[:path], "colon-separated array path did not match") - end - - def test_checks_apply_to_refresh - file = tempfile - maker = tempfile - - exec = Puppet::Type.type(:exec).new( - :title => "maker", - :command => "touch #{maker}", - :path => ENV["PATH"] - ) - - # Make sure it runs normally - assert_apply(exec) - assert(FileTest.exists?(maker), "exec did not run") - File.unlink(maker) - - # Now make sure it refreshes - assert_nothing_raised("Failed to refresh exec") do - exec.refresh - end - assert(FileTest.exists?(maker), "exec did not run refresh") - File.unlink(maker) - - # Now add the checks - exec[:creates] = file - - # Make sure it runs when the file doesn't exist - assert_nothing_raised("Failed to refresh exec") do - exec.refresh - end - assert(FileTest.exists?(maker), "exec did not refresh when checks passed") - File.unlink(maker) - - # Now create the file and make sure it doesn't refresh - File.open(file, "w") { |f| f.puts "" } - assert_nothing_raised("Failed to refresh exec") do - exec.refresh - end - assert(! FileTest.exists?(maker), "exec refreshed with failing checks") - end - - def test_explicit_refresh - refresher = tempfile - maker = tempfile - - exec = Puppet::Type.type(:exec).new( - :title => "maker", - :command => "touch #{maker}", - :path => ENV["PATH"] - ) - - # Call refresh normally - assert_nothing_raised do - exec.refresh - end - - # Make sure it created the normal file - assert(FileTest.exists?(maker), "normal refresh did not work") - File.unlink(maker) - - # Now reset refresh, and make sure it wins - assert_nothing_raised("Could not set refresh parameter") do - exec[:refresh] = "touch #{refresher}" - end - assert_nothing_raised do - exec.refresh - end - - # Make sure it created the normal file - assert(FileTest.exists?(refresher), "refresh param was ignored") - assert(! FileTest.exists?(maker), "refresh param also ran command") - end - - if Puppet.features.root? - def test_autorequire_user - user = Puppet::Type.type(:user).new(:name => "yay") - exec = Puppet::Type.type(:exec).new(:command => "/bin/echo fun", :user => "yay") - - rels = nil - assert_nothing_raised("Could not evaluate autorequire") do - rels = exec.autorequire - end - assert(rels.find { |r| r.source == user and r.target == exec }, "Exec did not autorequire user") - end - end -end diff --git a/test/ral/type/file.rb b/test/ral/type/file.rb deleted file mode 100755 index 2285e72c8..000000000 --- a/test/ral/type/file.rb +++ /dev/null @@ -1,912 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'puppettest/support/utils' -require 'fileutils' -require 'mocha' - -class TestFile < Test::Unit::TestCase - include PuppetTest::Support::Utils - include PuppetTest::FileTesting - - def mkfile(hash) - file = nil - assert_nothing_raised { - file = Puppet::Type.type(:file).new(hash) - } - file - end - - def mktestfile - tmpfile = tempfile - File.open(tmpfile, "w") { |f| f.puts rand(100) } - @@tmpfiles.push tmpfile - mkfile(:name => tmpfile) - end - - def setup - super - @file = Puppet::Type.type(:file) - $method = @method_name - Puppet[:filetimeout] = -1 - Facter.stubs(:to_hash).returns({}) - end - - def teardown - system("rm -rf #{Puppet[:statefile]}") - super - end - - def initstorage - Puppet::Util::Storage.init - Puppet::Util::Storage.load - end - - def clearstorage - Puppet::Util::Storage.store - Puppet::Util::Storage.clear - end - - def test_owner - file = mktestfile - - users = {} - count = 0 - - # collect five users - Etc.passwd { |passwd| - if count > 5 - break - else - count += 1 - end - users[passwd.uid] = passwd.name - } - - fake = {} - # find a fake user - while true - a = rand(1000) - begin - Etc.getpwuid(a) - rescue - fake[a] = "fakeuser" - break - end - end - - uid, name = users.shift - us = {} - us[uid] = name - users.each { |uid, name| - assert_apply(file) - assert_nothing_raised { - file[:owner] = name - } - assert_nothing_raised { - file.retrieve - } - assert_apply(file) - } - end - - def test_group - file = mktestfile - [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group| - assert_nothing_raised { - file[:group] = group - } - assert(file.property(:group)) - assert(file.property(:group).should) - } - end - - def test_groups_fails_when_invalid - assert_raise(Puppet::Error, "did not fail when the group was empty") do - Puppet::Type.type(:file).new :path => "/some/file", :group => "" - end - end - - if Puppet.features.root? - def test_createasuser - dir = tmpdir - - user = nonrootuser - path = File.join(tmpdir, "createusertesting") - @@tmpfiles << path - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :path => path, - :owner => user.name, - :ensure => "file", - - :mode => "755" - ) - } - - comp = mk_catalog("createusertest", file) - - assert_events([:file_created], comp) - end - - def test_nofollowlinks - basedir = tempfile - Dir.mkdir(basedir) - file = File.join(basedir, "file") - link = File.join(basedir, "link") - - File.open(file, "w", 0644) { |f| f.puts "yayness"; f.flush } - File.symlink(file, link) - - # First test 'user' - user = nonrootuser - - inituser = File.lstat(link).uid - File.lchown(inituser, nil, link) - - obj = nil - assert_nothing_raised { - - obj = Puppet::Type.type(:file).new( - - :title => link, - - :owner => user.name - ) - } - obj.retrieve - - # Make sure it defaults to managing the link - assert_events([:file_changed], obj) - assert_equal(user.uid, File.lstat(link).uid) - assert_equal(inituser, File.stat(file).uid) - File.chown(inituser, nil, file) - File.lchown(inituser, nil, link) - - # Try following - obj[:links] = :follow - assert_events([:file_changed], obj) - assert_equal(user.uid, File.stat(file).uid) - assert_equal(inituser, File.lstat(link).uid) - - # And then explicitly managing - File.chown(inituser, nil, file) - File.lchown(inituser, nil, link) - obj[:links] = :manage - assert_events([:file_changed], obj) - assert_equal(user.uid, File.lstat(link).uid) - assert_equal(inituser, File.stat(file).uid) - - obj.delete(:owner) - obj[:links] = :follow - - # And then test 'group' - group = nonrootgroup - - initgroup = File.stat(file).gid - obj[:group] = group.name - - obj[:links] = :follow - assert_events([:file_changed], obj) - assert_equal(group.gid, File.stat(file).gid) - File.chown(nil, initgroup, file) - File.lchown(nil, initgroup, link) - - obj[:links] = :manage - assert_events([:file_changed], obj) - assert_equal(group.gid, File.lstat(link).gid) - assert_equal(initgroup, File.stat(file).gid) - end - - def test_ownerasroot - file = mktestfile - - users = {} - count = 0 - - # collect five users - Etc.passwd { |passwd| - if count > 5 - break - else - count += 1 - end - next if passwd.uid < 0 - users[passwd.uid] = passwd.name - } - - fake = {} - # find a fake user - while true - a = rand(1000) - begin - Etc.getpwuid(a) - rescue - fake[a] = "fakeuser" - break - end - end - - users.each { |uid, name| - assert_nothing_raised { - file[:owner] = name - } - assert_apply(file) - currentvalue = file.retrieve - assert(file.insync?(currentvalue)) - assert_nothing_raised { - file[:owner] = uid - } - assert_apply(file) - currentvalue = file.retrieve - # make sure changing to number doesn't cause a sync - assert(file.insync?(currentvalue)) - } - - # We no longer raise an error here, because we check at run time - #fake.each { |uid, name| - # assert_raise(Puppet::Error) { - # file[:owner] = name - # } - # assert_raise(Puppet::Error) { - # file[:owner] = uid - # } - #} - end - - def test_groupasroot - file = mktestfile - [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group| - next unless Puppet::Util.gid(group) # grr. - assert_nothing_raised { - file[:group] = group - } - assert(file.property(:group)) - assert(file.property(:group).should) - assert_apply(file) - currentvalue = file.retrieve - assert(file.insync?(currentvalue)) - assert_nothing_raised { - file.delete(:group) - } - } - end - - if Facter.value(:operatingsystem) == "Darwin" - def test_sillyowner - file = tempfile - File.open(file, "w") { |f| f.puts "" } - File.chown(-2, nil, file) - - assert(File.stat(file).uid > 120000, "eh?") - user = nonrootuser - - obj = Puppet::Type.newfile( - - :path => file, - - :owner => user.name - ) - - assert_apply(obj) - - assert_equal(user.uid, File.stat(file).uid) - end - end - else - $stderr.puts "Run as root for complete owner and group testing" - end - - def test_create - %w{a b c d}.collect { |name| tempfile + name.to_s }.each { |path| - file =nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => path, - - :ensure => "file" - ) - } - assert_events([:file_created], file) - assert_events([], file) - assert(FileTest.file?(path), "File does not exist") - @@tmpfiles.push path - } - end - - def test_create_dir - basedir = tempfile - Dir.mkdir(basedir) - %w{a b c d}.collect { |name| "#{basedir}/#{name}" }.each { |path| - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => path, - - :ensure => "directory" - ) - } - assert(! FileTest.directory?(path), "Directory #{path} already exists") - assert_events([:directory_created], file) - assert_events([], file) - assert(FileTest.directory?(path)) - @@tmpfiles.push path - } - end - - def test_modes - file = mktestfile - # Set it to something else initially - File.chmod(0775, file.title) - [0644,0755,0777,0641].each { |mode| - assert_nothing_raised { - file[:mode] = mode - } - assert_events([:mode_changed], file) - assert_events([], file) - - assert_nothing_raised { - file.delete(:mode) - } - } - end - - def cyclefile(path) - # i had problems with using :name instead of :path - [:name,:path].each { |param| - file = nil - changes = nil - comp = nil - trans = nil - - initstorage - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - param => path, - :recurse => true, - - :checksum => "md5" - ) - } - comp = Puppet::Type.type(:component).new( - :name => "component" - ) - comp.push file - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } - clearstorage - Puppet::Type.allclear - } - end - - def test_filetype_retrieval - file = nil - - # Verify it retrieves files of type directory - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => tmpdir, - - :check => :type - ) - } - - assert_equal("directory", file.property(:type).retrieve) - - # And then check files - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => tempfile, - - :ensure => "file" - ) - } - - assert_apply(file) - file[:check] = "type" - assert_apply(file) - - assert_equal("file", file.property(:type).retrieve) - end - - def test_path - dir = tempfile - - path = File.join(dir, "subdir") - - assert_nothing_raised("Could not make file") { - FileUtils.mkdir_p(File.dirname(path)) - File.open(path, "w") { |f| f.puts "yayness" } - } - - file = nil - dirobj = nil - assert_nothing_raised("Could not make file object") { - - dirobj = Puppet::Type.type(:file).new( - - :path => dir, - :recurse => true, - - :check => %w{mode owner group} - ) - } - catalog = mk_catalog dirobj - transaction = Puppet::Transaction.new(catalog) - transaction.eval_generate(dirobj) - - #assert_nothing_raised { - # dirobj.eval_generate - #} - - file = catalog.resource(:file, path) - - assert(file, "Could not retrieve file object") - - assert_equal("/#{file.ref}", file.path) - end - - def test_autorequire - basedir = tempfile - subfile = File.join(basedir, "subfile") - - - baseobj = Puppet::Type.type(:file).new( - - :name => basedir, - - :ensure => "directory" - ) - - - subobj = Puppet::Type.type(:file).new( - - :name => subfile, - - :ensure => "file" - ) - catalog = mk_catalog(baseobj, subobj) - edge = nil - assert_nothing_raised do - edge = subobj.autorequire.shift - end - assert_equal(baseobj, edge.source, "file did not require its parent dir") - assert_equal(subobj, edge.target, "file did not require its parent dir") - end - - # Unfortunately, I know this fails - def disabled_test_recursivemkdir - path = tempfile - subpath = File.join(path, "this", "is", "a", "dir") - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => subpath, - :ensure => "directory", - - :recurse => true - ) - } - - comp = mk_catalog("yay", file) - comp.finalize - assert_apply(comp) - #assert_events([:directory_created], comp) - - assert(FileTest.directory?(subpath), "Did not create directory") - end - - # Make sure that content updates the checksum on the same run - def test_checksumchange_for_content - dest = tempfile - File.open(dest, "w") { |f| f.puts "yayness" } - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => dest, - :checksum => "md5", - :content => "This is some content", - - :backup => false - ) - } - - file.retrieve - - assert_events([:content_changed], file) - file.retrieve - assert_events([], file) - end - - # Make sure that content updates the checksum on the same run - def test_checksumchange_for_ensure - dest = tempfile - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => dest, - :checksum => "md5", - - :ensure => "file" - ) - } - - file.retrieve - - assert_events([:file_created], file) - file.retrieve - assert_events([], file) - end - - def test_nameandpath - path = tempfile - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :title => "fileness", - :path => path, - - :content => "this is some content" - ) - } - - assert_apply(file) - - assert(FileTest.exists?(path)) - end - - # Make sure that a missing group isn't fatal at object instantiation time. - def test_missinggroup - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :path => tempfile, - - :group => "fakegroup" - ) - } - - assert(file.property(:group), "Group property failed") - end - - def test_modecreation - path = tempfile - - file = Puppet::Type.type(:file).new( - - :path => path, - :ensure => "file", - - :mode => "0777" - ) - assert_equal("777", file.should(:mode), "Mode did not get set correctly") - assert_apply(file) - assert_equal(0777, File.stat(path).mode & 007777, "file mode is incorrect") - File.unlink(path) - file[:ensure] = "directory" - assert_apply(file) - assert_equal(0777, File.stat(path).mode & 007777, "directory mode is incorrect") - end - - # If both 'ensure' and 'content' are used, make sure that all of the other - # properties are handled correctly. - def test_contentwithmode - path = tempfile - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :path => path, - :ensure => "file", - :content => "some text\n", - - :mode => 0755 - ) - } - - assert_apply(file) - assert_equal("%o" % 0755, "%o" % (File.stat(path).mode & 007777)) - end - - def test_replacefilewithlink - path = tempfile - link = tempfile - - File.open(path, "w") { |f| f.puts "yay" } - File.open(link, "w") { |f| f.puts "a file" } - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :ensure => path, - :path => link, - - :backup => false - ) - } - - assert_events([:link_created], file) - - assert(FileTest.symlink?(link), "Link was not created") - - assert_equal(path, File.readlink(link), "Link was created incorrectly") - end - - def test_file_with_spaces - dir = tempfile - Dir.mkdir(dir) - source = File.join(dir, "file spaces") - dest = File.join(dir, "another space") - - File.open(source, "w") { |f| f.puts :yay } - - obj = Puppet::Type.type(:file).new( - - :path => dest, - - :source => source - ) - assert(obj, "Did not create file") - - assert_apply(obj) - - assert(FileTest.exists?(dest), "File did not get created") - end - - # Testing #274. Make sure target can be used without 'ensure'. - def test_target_without_ensure - source = tempfile - dest = tempfile - File.open(source, "w") { |f| f.puts "funtest" } - - obj = nil - assert_nothing_raised { - obj = Puppet::Type.newfile(:path => dest, :target => source) - } - - assert_apply(obj) - end - - def test_autorequire_owner_and_group - file = tempfile - comp = nil - user = nil - group =nil - home = nil - ogroup = nil - assert_nothing_raised { - - user = Puppet::Type.type(:user).new( - - :name => "pptestu", - :home => file, - - :gid => "pptestg" - ) - - home = Puppet::Type.type(:file).new( - - :path => file, - :owner => "pptestu", - :group => "pptestg", - - :ensure => "directory" - ) - group = Puppet::Type.type(:group).new( - :name => "pptestg" - ) - comp = mk_catalog(user, group, home) - } - - # Now make sure we get a relationship for each of these - rels = nil - assert_nothing_raised { rels = home.autorequire } - assert(rels.detect { |e| e.source == user }, "owner was not autorequired") - assert(rels.detect { |e| e.source == group }, "group was not autorequired") - end - - # Testing #309 -- //my/file => /my/file - def test_slash_deduplication - ["/my/////file/for//testing", "/my/file/for/testing///", - "/my/file/for/testing"].each do |path| - file = nil - assert_nothing_raised do - file = Puppet::Type.newfile(:path => path) - end - - assert_equal("/my/file/for/testing", file[:path]) - end - end - - if Process.uid == 0 - # Testing #364. - def test_writing_in_directories_with_no_write_access - # Make a directory that our user does not have access to - dir = tempfile - Dir.mkdir(dir) - - # Get a fake user - user = nonrootuser - # and group - group = nonrootgroup - - # First try putting a file in there - path = File.join(dir, "file") - file = Puppet::Type.newfile :path => path, :owner => user.name, :group => group.name, :content => "testing" - - # Make sure we can create it - assert_apply(file) - assert(FileTest.exists?(path), "File did not get created") - # And that it's owned correctly - assert_equal(user.uid, File.stat(path).uid, "File has the wrong owner") - assert_equal(group.gid, File.stat(path).gid, "File has the wrong group") - - assert_equal("testing", File.read(path), "file has the wrong content") - - # Now make a dir - subpath = File.join(dir, "subdir") - subdir = Puppet::Type.newfile :path => subpath, :owner => user.name, :group => group.name, :ensure => :directory - # Make sure we can create it - assert_apply(subdir) - assert(FileTest.directory?(subpath), "File did not get created") - # And that it's owned correctly - assert_equal(user.uid, File.stat(subpath).uid, "File has the wrong owner") - assert_equal(group.gid, File.stat(subpath).gid, "File has the wrong group") - - assert_equal("testing", File.read(path), "file has the wrong content") - end - end - - # #366 - def test_replace_aliases - file = Puppet::Type.newfile :path => tempfile - file[:replace] = :yes - assert_equal(:true, file[:replace], ":replace did not alias :true to :yes") - file[:replace] = :no - assert_equal(:false, file[:replace], ":replace did not alias :false to :no") - end - - def test_pathbuilder - dir = tempfile - Dir.mkdir(dir) - file = File.join(dir, "file") - File.open(file, "w") { |f| f.puts "" } - obj = Puppet::Type.newfile :path => dir, :recurse => true, :mode => 0755 - catalog = mk_catalog obj - transaction = Puppet::Transaction.new(catalog) - - assert_equal("/#{obj.ref}", obj.path) - - list = transaction.eval_generate(obj) - fileobj = catalog.resource(:file, file) - assert(fileobj, "did not generate file object") - assert_equal("/#{fileobj.ref}", fileobj.path, "did not generate correct subfile path") - end - - # Testing #403 - def test_removal_with_content_set - path = tempfile - File.open(path, "w") { |f| f.puts "yay" } - file = Puppet::Type.newfile(:name => path, :ensure => :absent, :content => "foo", :backup => false) - - assert_apply(file) - assert(! FileTest.exists?(path), "File was not removed") - end - - # Testing #438 - def test_creating_properties_conflict - file = tempfile - first = tempfile - second = tempfile - params = [:content, :source, :target] - params.each do |param| - assert_nothing_raised("#{param} conflicted with ensure") do - Puppet::Type.newfile(:path => file, param => first, :ensure => :file) - end - params.each do |other| - next if other == param - assert_raise(Puppet::Error, "#{param} and #{other} did not conflict") do - Puppet::Type.newfile(:path => file, other => first, param => second) - end - end - end - end - - # Testing #508 - if Process.uid == 0 - def test_files_replace_with_right_attrs - source = tempfile - File.open(source, "w") { |f| - f.puts "some text" - } - File.chmod(0755, source) - user = nonrootuser - group = nonrootgroup - path = tempfile - good = {:uid => user.uid, :gid => group.gid, :mode => 0640} - - run = Proc.new do |obj, msg| - assert_apply(obj) - stat = File.stat(obj[:path]) - good.each do |should, sval| - if should == :mode - current = filemode(obj[:path]) - else - current = stat.send(should) - end - assert_equal(sval, current, "Attr #{should} was not correct #{msg}") - end - end - - - file = Puppet::Type.newfile( - :path => path, :owner => user.name, - - :group => group.name, :mode => 0640, :backup => false) - {:source => source, :content => "some content"}.each do |attr, value| - file[attr] = value - # First create the file - run.call(file, "upon creation with #{attr}") - - # Now change something so that we replace the file - case attr - when :source - File.open(source, "w") { |f| f.puts "some different text" } - when :content; file[:content] = "something completely different" - else - raise "invalid attr #{attr}" - end - - # Run it again - run.call(file, "after modification with #{attr}") - - # Now remove the file and the attr - file.delete(attr) - File.unlink(path) - end - end - end - - def test_root_dir_is_named_correctly - obj = Puppet::Type.newfile(:path => '/', :mode => 0755) - assert_equal("/", obj.title, "/ directory was changed to empty string") - end - -end diff --git a/test/ral/type/file/target.rb b/test/ral/type/file/target.rb deleted file mode 100755 index d778f2891..000000000 --- a/test/ral/type/file/target.rb +++ /dev/null @@ -1,346 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../../lib/puppettest') - -require 'puppettest' -require 'puppettest/support/utils' -require 'fileutils' - -class TestFileTarget < Test::Unit::TestCase - include PuppetTest::Support::Utils - include PuppetTest::FileTesting - - def setup - super - @file = Puppet::Type.type(:file) - end - - # Make sure we can create symlinks - def test_symlinks - path = tempfile - link = tempfile - - File.open(path, "w") { |f| f.puts "yay" } - - file = nil - assert_nothing_raised { - file = Puppet::Type.type(:file).new( - :title => "somethingelse", - :ensure => path, - :path => link - ) - } - - assert_events([:link_created], file) - - assert(FileTest.symlink?(link), "Link was not created") - - assert_equal(path, File.readlink(link), "Link was created incorrectly") - - # Make sure running it again works - assert_events([], file) - assert_events([], file) - assert_events([], file) - end - - def test_simplerecursivelinking - source = tempfile - path = tempfile - subdir = File.join(source, "subdir") - file = File.join(subdir, "file") - - system("mkdir -p #{subdir}") - system("touch #{file}") - - - link = Puppet::Type.type(:file).new( - - :ensure => source, - :path => path, - - :recurse => true - ) - - catalog = mk_catalog(link) - catalog.apply - - sublink = File.join(path, "subdir") - linkpath = File.join(sublink, "file") - assert(File.directory?(path), "dest is not a dir") - assert(File.directory?(sublink), "subdest is not a dir") - assert(File.symlink?(linkpath), "path is not a link") - assert_equal(file, File.readlink(linkpath)) - - # Use classes for comparison, because the resource inspection is so large - assert_events([], link, "Link is not in sync") - end - - def test_recursivelinking - source = tempfile - dest = tempfile - - files = [] - dirs = [] - - # Make a bunch of files and dirs - Dir.mkdir(source) - Dir.chdir(source) do - system("mkdir -p #{"some/path/of/dirs"}") - system("mkdir -p #{"other/path/of/dirs"}") - system("touch #{"file"}") - system("touch #{"other/file"}") - system("touch #{"some/path/of/file"}") - system("touch #{"some/path/of/dirs/file"}") - system("touch #{"other/path/of/file"}") - - files = %x{find . -type f}.chomp.split(/\n/) - dirs = %x{find . -type d}.chomp.split(/\n/).reject{|d| d =~ /^\.+$/ } - end - - link = nil - assert_nothing_raised { - link = Puppet::Type.type(:file).new( - :ensure => source, - :path => dest, - :recurse => true - ) - } - - assert_apply(link) - - files.each do |f| - f.sub!(/^\.#{File::SEPARATOR}/, '') - path = File.join(dest, f) - assert(FileTest.exists?(path), "Link #{path} was not created") - assert(FileTest.symlink?(path), "#{f} is not a link") - target = File.readlink(path) - assert_equal(File.join(source, f), target) - end - - dirs.each do |d| - d.sub!(/^\.#{File::SEPARATOR}/, '') - path = File.join(dest, d) - assert(FileTest.exists?(path), "Dir #{path} was not created") - assert(FileTest.directory?(path), "#{d} is not a directory") - end - end - - def test_localrelativelinks - dir = tempfile - Dir.mkdir(dir) - source = File.join(dir, "source") - File.open(source, "w") { |f| f.puts "yay" } - dest = File.join(dir, "link") - - link = nil - assert_nothing_raised { - link = Puppet::Type.type(:file).new( - :path => dest, - :ensure => "source" - ) - } - - assert_events([:link_created], link) - assert(FileTest.symlink?(dest), "Did not create link") - assert_equal("source", File.readlink(dest)) - assert_equal("yay\n", File.read(dest)) - end - - def test_recursivelinkingmissingtarget - source = tempfile - dest = tempfile - - resources = [] - - resources << Puppet::Type.type(:exec).new( - :command => "mkdir #{source}; touch #{source}/file", - :title => "yay", - :path => ENV["PATH"] - ) - - resources << Puppet::Type.type(:file).new( - :ensure => source, - :path => dest, - :recurse => true, - :require => resources[0] - ) - - assert_apply(*resources) - - link = File.join(dest, "file") - assert(FileTest.symlink?(link), "Did not make link") - assert_equal(File.join(source, "file"), File.readlink(link)) - end - - def test_insync? - source = tempfile - dest = tempfile - - obj = @file.create(:path => source, :target => dest) - - prop = obj.send(:property, :target) - prop.send(:instance_variable_set, "@should", [:nochange]) - - assert( - prop.insync?(prop.retrieve), - - "Property not in sync with should == :nochange") - - prop = obj.send(:property, :target) - prop.send(:instance_variable_set, "@should", [:notlink]) - - assert( - prop.insync?(prop.retrieve), - - "Property not in sync with should == :nochange") - - # Lastly, make sure that we don't try to do anything when we're - # recursing, since 'ensure' does the work. - obj[:recurse] = true - prop.should = dest - - assert( - prop.insync?(prop.retrieve), - - "Still out of sync during recursion") - end - - def test_replacedirwithlink - Puppet[:trace] = false - path = tempfile - link = tempfile - - File.open(path, "w") { |f| f.puts "yay" } - Dir.mkdir(link) - File.open(File.join(link, "yay"), "w") do |f| f.puts "boo" end - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :ensure => path, - :path => link, - - :backup => false - ) - } - - # First run through without :force - assert_events([], file) - - assert(FileTest.directory?(link), "Link replaced dir without force") - - assert_nothing_raised { file[:force] = true } - - assert_events([:link_created], file) - - assert(FileTest.symlink?(link), "Link was not created") - - assert_equal(path, File.readlink(link), "Link was created incorrectly") - end - - def test_replace_links_with_files - base = tempfile - - Dir.mkdir(base) - - file = File.join(base, "file") - link = File.join(base, "link") - File.open(file, "w") { |f| f.puts "yayness" } - File.symlink(file, link) - - - obj = Puppet::Type.type(:file).new( - - :path => link, - - :ensure => "file" - ) - - assert_apply(obj) - - - assert_equal( - "yayness\n", File.read(file), - - "Original file got changed") - assert_equal("file", File.lstat(link).ftype, "File is still a link") - end - - def test_no_erase_linkedto_files - base = tempfile - - Dir.mkdir(base) - - dirs = {} - %w{other source target}.each do |d| - dirs[d] = File.join(base, d) - Dir.mkdir(dirs[d]) - end - - file = File.join(dirs["other"], "file") - sourcefile = File.join(dirs["source"], "sourcefile") - link = File.join(dirs["target"], "sourcefile") - - File.open(file, "w") { |f| f.puts "other" } - File.open(sourcefile, "w") { |f| f.puts "source" } - File.symlink(file, link) - - - obj = Puppet::Type.type(:file).new( - - :path => dirs["target"], - :ensure => :file, - :source => dirs["source"], - - :recurse => true - ) - config = mk_catalog obj - config.apply - - newfile = File.join(dirs["target"], "sourcefile") - - assert(File.directory?(dirs["target"]), "Dir did not get created") - assert(File.file?(newfile), "File did not get copied") - - assert_equal(File.read(sourcefile), File.read(newfile), - "File did not get copied correctly.") - - - assert_equal( - "other\n", File.read(file), - - "Original file got changed") - assert_equal("file", File.lstat(link).ftype, "File is still a link") - end - - def test_replace_links - dest = tempfile - otherdest = tempfile - link = tempfile - - File.open(dest, "w") { |f| f.puts "boo" } - File.open(otherdest, "w") { |f| f.puts "yay" } - - - obj = Puppet::Type.type(:file).new( - - :path => link, - - :ensure => otherdest - ) - - - assert_apply(obj) - - assert_equal(otherdest, File.readlink(link), "Link did not get created") - - obj[:ensure] = dest - - assert_apply(obj) - - assert_equal(dest, File.readlink(link), "Link did not get changed") - end -end - diff --git a/test/ral/type/fileignoresource.rb b/test/ral/type/fileignoresource.rb deleted file mode 100755 index 593fcf7a7..000000000 --- a/test/ral/type/fileignoresource.rb +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'puppettest/support/utils' -require 'cgi' -require 'fileutils' - -class TestFileIgnoreSources < Test::Unit::TestCase - include PuppetTest::Support::Utils - include PuppetTest::FileTesting - - def setup - super - begin - initstorage - rescue - system("rm -rf #{Puppet[:statefile]}") - end - - Facter.stubs(:to_hash).returns({}) - end - -#This is not needed unless using md5 (correct me if I'm wrong) - def initstorage - Puppet::Util::Storage.init - Puppet::Util::Storage.load - end - - def clearstorage - Puppet::Util::Storage.store - Puppet::Util::Storage.clear - end - - def test_ignore_simple_source - - #Temp directory to run tests in - path = tempfile - @@tmpfiles.push path - - #source directory - sourcedir = "sourcedir" - sourcefile1 = "sourcefile1" - sourcefile2 = "sourcefile2" - - frompath = File.join(path,sourcedir) - FileUtils.mkdir_p frompath - - topath = File.join(path,"destdir") - FileUtils.mkdir topath - - #initialize variables before block - tofile = nil - trans = nil - - #create source files - - - File.open( - File.join(frompath,sourcefile1), - - File::WRONLY|File::CREAT|File::APPEND) { |of| - of.puts "yayness" - } - - - File.open( - File.join(frompath,sourcefile2), - - File::WRONLY|File::CREAT|File::APPEND) { |of| - of.puts "even yayer" - } - - - #makes Puppet file Object - assert_nothing_raised { - - tofile = Puppet::Type.type(:file).new( - - :name => topath, - :source => frompath, - :recurse => true, - - :ignore => "sourcefile2" - ) - } - - config = mk_catalog(tofile) - config.apply - - - #topath should exist as a directory with sourcedir as a directory - - #This file should exist - assert(FileTest.exists?(File.join(topath,sourcefile1))) - - #This file should not - assert(!(FileTest.exists?(File.join(topath,sourcefile2)))) - end - - def test_ignore_with_wildcard - #Temp directory to run tests in - path = tempfile - @@tmpfiles.push path - - #source directory - sourcedir = "sourcedir" - subdir = "subdir" - subdir2 = "subdir2" - sourcefile1 = "sourcefile1" - sourcefile2 = "sourcefile2" - - frompath = File.join(path,sourcedir) - FileUtils.mkdir_p frompath - - FileUtils.mkdir_p(File.join(frompath, subdir)) - FileUtils.mkdir_p(File.join(frompath, subdir2)) - dir = Dir.glob(File.join(path,"**/*")) - - topath = File.join(path,"destdir") - FileUtils.mkdir topath - - #initialize variables before block - tofile = nil - trans = nil - - #create source files - - dir.each { |dir| - - File.open( - File.join(dir,sourcefile1), - - File::WRONLY|File::CREAT|File::APPEND) { |of| - of.puts "yayness" - } - - - File.open( - File.join(dir,sourcefile2), - - File::WRONLY|File::CREAT|File::APPEND) { |of| - of.puts "even yayer" - } - - } - - #makes Puppet file Object - assert_nothing_raised { - - tofile = Puppet::Type.type(:file).new( - - :name => topath, - :source => frompath, - :recurse => true, - - :ignore => "*2" - ) - } - - config = mk_catalog(tofile) - config.apply - - #topath should exist as a directory with sourcedir as a directory - - #This file should exist - assert(FileTest.exists?(File.join(topath,sourcefile1))) - assert(FileTest.exists?(File.join(topath,subdir))) - assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1))) - - #This file should not - assert(!(FileTest.exists?(File.join(topath,sourcefile2)))) - assert(!(FileTest.exists?(File.join(topath,subdir2)))) - assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2)))) - end - - def test_ignore_array - #Temp directory to run tests in - path = tempfile - @@tmpfiles.push path - - #source directory - sourcedir = "sourcedir" - subdir = "subdir" - subdir2 = "subdir2" - subdir3 = "anotherdir" - sourcefile1 = "sourcefile1" - sourcefile2 = "sourcefile2" - - frompath = File.join(path,sourcedir) - FileUtils.mkdir_p frompath - - FileUtils.mkdir_p(File.join(frompath, subdir)) - FileUtils.mkdir_p(File.join(frompath, subdir2)) - FileUtils.mkdir_p(File.join(frompath, subdir3)) - sourcedir = Dir.glob(File.join(path,"**/*")) - - topath = File.join(path,"destdir") - FileUtils.mkdir topath - - #initialize variables before block - tofile = nil - trans = nil - - #create source files - - - - sourcedir.each { |dir| - - File.open( - File.join(dir,sourcefile1), - - File::WRONLY|File::CREAT|File::APPEND) { |of| - of.puts "yayness" - } - - - File.open( - File.join(dir,sourcefile2), - - File::WRONLY|File::CREAT|File::APPEND) { |of| - of.puts "even yayer" - } - - } - - - #makes Puppet file Object - assert_nothing_raised { - - tofile = Puppet::Type.type(:file).new( - - :name => topath, - :source => frompath, - :recurse => true, - - :ignore => ["*2", "an*"] - # :ignore => ["*2", "an*", "nomatch"] - ) - } - - config = mk_catalog(tofile) - config.apply - - #topath should exist as a directory with sourcedir as a directory - - # This file should exist - # proper files in destination - assert(FileTest.exists?(File.join(topath,sourcefile1)), "file1 not in destdir") - assert(FileTest.exists?(File.join(topath,subdir)), "subdir1 not in destdir") - assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1)), "file1 not in subdir") - # proper files in source - assert(FileTest.exists?(File.join(frompath,subdir)), "subdir not in source") - assert(FileTest.exists?(File.join(frompath,subdir2)), "subdir2 not in source") - assert(FileTest.exists?(File.join(frompath,subdir3)), "subdir3 not in source") - - # This file should not - assert(!(FileTest.exists?(File.join(topath,sourcefile2))), "file2 in dest") - assert(!(FileTest.exists?(File.join(topath,subdir2))), "subdir2 in dest") - assert(!(FileTest.exists?(File.join(topath,subdir3))), "anotherdir in dest") - assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2))), "file2 in dest/sub") - end -end diff --git a/test/ral/type/filesources.rb b/test/ral/type/filesources.rb deleted file mode 100755 index 9cb7efbf0..000000000 --- a/test/ral/type/filesources.rb +++ /dev/null @@ -1,446 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'puppettest/support/utils' -require 'cgi' -require 'fileutils' -require 'mocha' - -class TestFileSources < Test::Unit::TestCase - include PuppetTest::Support::Utils - include PuppetTest::FileTesting - def setup - super - if defined?(@port) - @port += 1 - else - @port = 12345 - end - @file = Puppet::Type.type(:file) - Puppet[:filetimeout] = -1 - Puppet::Util::SUIDManager.stubs(:asuser).yields - Facter.stubs(:to_hash).returns({}) - end - - def teardown - super - end - - def use_storage - initstorage - rescue - system("rm -rf #{Puppet[:statefile]}") - end - - def initstorage - Puppet::Util::Storage.init - Puppet::Util::Storage.load - end - - # Make a simple recursive tree. - def mk_sourcetree - source = tempfile - sourcefile = File.join(source, "file") - Dir.mkdir source - File.open(sourcefile, "w") { |f| f.puts "yay" } - - dest = tempfile - destfile = File.join(dest, "file") - return source, dest, sourcefile, destfile - end - - def recursive_source_test(fromdir, todir) - initstorage - tofile = nil - trans = nil - - - tofile = Puppet::Type.type(:file).new( - - :path => todir, - :recurse => true, - :backup => false, - - :source => fromdir - ) - catalog = mk_catalog(tofile) - catalog.apply - - assert(FileTest.exists?(todir), "Created dir #{todir} does not exist") - end - - def run_complex_sources(networked = false) - path = tempfile - - # first create the source directory - FileUtils.mkdir_p path - - # okay, let's create a directory structure - fromdir = File.join(path,"fromdir") - Dir.mkdir(fromdir) - FileUtils.cd(fromdir) { - File.open("one", "w") { |f| f.puts "onefile"} - File.open("two", "w") { |f| f.puts "twofile"} - } - - todir = File.join(path, "todir") - source = fromdir - source = "puppet://localhost/#{networked}#{fromdir}" if networked - recursive_source_test(source, todir) - - [fromdir,todir, File.join(todir, "one"), File.join(todir, "two")] - end - - def test_complex_sources_twice - fromdir, todir, one, two = run_complex_sources - assert_trees_equal(fromdir,todir) - recursive_source_test(fromdir, todir) - assert_trees_equal(fromdir,todir) - # Now remove the whole tree and try it again. - [one, two].each do |f| File.unlink(f) end - Dir.rmdir(todir) - recursive_source_test(fromdir, todir) - assert_trees_equal(fromdir,todir) - end - - def test_sources_with_deleted_destfiles - fromdir, todir, one, two = run_complex_sources - assert(FileTest.exists?(todir)) - - # then delete a file - File.unlink(two) - - # and run - recursive_source_test(fromdir, todir) - - assert(FileTest.exists?(two), "Deleted file was not recopied") - - # and make sure they're still equal - assert_trees_equal(fromdir,todir) - end - - def test_sources_with_readonly_destfiles - fromdir, todir, one, two = run_complex_sources - assert(FileTest.exists?(todir)) - File.chmod(0600, one) - recursive_source_test(fromdir, todir) - - # and make sure they're still equal - assert_trees_equal(fromdir,todir) - - # Now try it with the directory being read-only - File.chmod(0111, todir) - recursive_source_test(fromdir, todir) - - # and make sure they're still equal - assert_trees_equal(fromdir,todir) - end - - def test_sources_with_modified_dest_files - fromdir, todir, one, two = run_complex_sources - - assert(FileTest.exists?(todir)) - - # Modify a dest file - File.open(two, "w") { |f| f.puts "something else" } - - recursive_source_test(fromdir, todir) - - # and make sure they're still equal - assert_trees_equal(fromdir,todir) - end - - def test_sources_with_added_destfiles - fromdir, todir = run_complex_sources - assert(FileTest.exists?(todir)) - # and finally, add some new files - add_random_files(todir) - - recursive_source_test(fromdir, todir) - - fromtree = file_list(fromdir) - totree = file_list(todir) - - assert(fromtree != totree, "Trees are incorrectly equal") - - # then remove our new files - FileUtils.cd(todir) { - %x{find . 2>/dev/null}.chomp.split(/\n/).each { |file| - if file =~ /file[0-9]+/ - FileUtils.rm_rf(file) - end - } - } - - # and make sure they're still equal - assert_trees_equal(fromdir,todir) - end - - # Make sure added files get correctly caught during recursion - def test_RecursionWithAddedFiles - basedir = tempfile - Dir.mkdir(basedir) - @@tmpfiles << basedir - file1 = File.join(basedir, "file1") - file2 = File.join(basedir, "file2") - subdir1 = File.join(basedir, "subdir1") - file3 = File.join(subdir1, "file") - File.open(file1, "w") { |f| f.puts "yay" } - rootobj = nil - assert_nothing_raised { - - rootobj = Puppet::Type.type(:file).new( - - :name => basedir, - :recurse => true, - :check => %w{type owner}, - - :mode => 0755 - ) - } - - assert_apply(rootobj) - assert_equal(0755, filemode(file1)) - - File.open(file2, "w") { |f| f.puts "rah" } - assert_apply(rootobj) - assert_equal(0755, filemode(file2)) - - Dir.mkdir(subdir1) - File.open(file3, "w") { |f| f.puts "foo" } - assert_apply(rootobj) - assert_equal(0755, filemode(file3)) - end - - def mkfileserverconf(mounts) - file = tempfile - File.open(file, "w") { |f| - mounts.each { |path, name| - f.puts "[#{name}]\n\tpath #{path}\n\tallow *\n" - } - } - - @@tmpfiles << file - file - end - - def test_sourcepaths - files = [] - 3.times { - files << tempfile - } - - to = tempfile - - File.open(files[-1], "w") { |f| f.puts "yee-haw" } - - file = nil - assert_nothing_raised { - - file = Puppet::Type.type(:file).new( - - :name => to, - - :source => files - ) - } - - comp = mk_catalog(file) - assert_events([:file_created], comp) - - assert(File.exists?(to), "File does not exist") - - txt = nil - File.open(to) { |f| txt = f.read.chomp } - - assert_equal("yee-haw", txt, "Contents do not match") - end - - # Make sure that source-copying updates the checksum on the same run - def test_sourcebeatsensure - source = tempfile - dest = tempfile - File.open(source, "w") { |f| f.puts "yay" } - - file = nil - assert_nothing_raised { - file = Puppet::Type.type(:file).new( - :name => dest, - :ensure => "file", - :source => source - ) - } - - file.retrieve - - assert_events([:file_created], file) - file.retrieve - assert_events([], file) - assert_events([], file) - end - - def test_sourcewithlinks - source = tempfile - link = tempfile - dest = tempfile - - File.open(source, "w") { |f| f.puts "yay" } - File.symlink(source, link) - - file = Puppet::Type.type(:file).new(:name => dest, :source => link) - - catalog = mk_catalog(file) - - # Default to managing links - catalog.apply - assert(FileTest.symlink?(dest), "Did not create link") - - # Now follow the links - file[:links] = :follow - catalog.apply - assert(FileTest.file?(dest), "Destination is not a file") - end - - # Make sure files aren't replaced when replace is false, but otherwise - # are. - def test_replace - dest = tempfile - - file = Puppet::Type.newfile( - - :path => dest, - :content => "foobar", - - :recurse => true - ) - - - assert_apply(file) - - File.open(dest, "w") { |f| f.puts "yayness" } - - file[:replace] = false - - assert_apply(file) - - # Make sure it doesn't change. - assert_equal("yayness\n", File.read(dest), "File got replaced when :replace was false") - - file[:replace] = true - assert_apply(file) - - # Make sure it changes. - assert_equal("foobar", File.read(dest), "File was not replaced when :replace was true") - end - - def test_sourceselect - dest = tempfile - sources = [] - 2.times { |i| - i = i + 1 - source = tempfile - sources << source - file = File.join(source, "file#{i}") - Dir.mkdir(source) - File.open(file, "w") { |f| f.print "yay" } - } - file1 = File.join(dest, "file1") - file2 = File.join(dest, "file2") - file3 = File.join(dest, "file3") - - # Now make different files with the same name in each source dir - sources.each_with_index do |source, i| - File.open(File.join(source, "file3"), "w") { |f| - f.print i.to_s - } - end - - - obj = Puppet::Type.newfile( - :path => dest, :recurse => true, - - :source => sources) - - assert_equal(:first, obj[:sourceselect], "sourceselect has the wrong default") - # First, make sure we default to just copying file1 - assert_apply(obj) - - assert(FileTest.exists?(file1), "File from source 1 was not copied") - assert(! FileTest.exists?(file2), "File from source 2 was copied") - assert(FileTest.exists?(file3), "File from source 1 was not copied") - assert_equal("0", File.read(file3), "file3 got wrong contents") - - # Now reset sourceselect - assert_nothing_raised do - obj[:sourceselect] = :all - end - File.unlink(file1) - File.unlink(file3) - Puppet.err :yay - assert_apply(obj) - - assert(FileTest.exists?(file1), "File from source 1 was not copied") - assert(FileTest.exists?(file2), "File from source 2 was copied") - assert(FileTest.exists?(file3), "File from source 1 was not copied") - assert_equal("0", File.read(file3), "file3 got wrong contents") - end - - def test_recursive_sourceselect - dest = tempfile - source1 = tempfile - source2 = tempfile - files = [] - [source1, source2, File.join(source1, "subdir"), File.join(source2, "subdir")].each_with_index do |dir, i| - Dir.mkdir(dir) - # Make a single file in each directory - file = File.join(dir, "file#{i}") - File.open(file, "w") { |f| f.puts "yay#{i}"} - - # Now make a second one in each directory - file = File.join(dir, "second-file#{i}") - File.open(file, "w") { |f| f.puts "yaysecond-#{i}"} - files << file - end - - obj = Puppet::Type.newfile(:path => dest, :source => [source1, source2], :sourceselect => :all, :recurse => true) - - assert_apply(obj) - - ["file0", "file1", "second-file0", "second-file1", "subdir/file2", "subdir/second-file2", "subdir/file3", "subdir/second-file3"].each do |file| - path = File.join(dest, file) - assert(FileTest.exists?(path), "did not create #{file}") - - assert_equal("yay#{File.basename(file).sub("file", '')}\n", File.read(path), "file was not copied correctly") - end - end - - # #594 - def test_purging_missing_remote_files - source = tempfile - dest = tempfile - s1 = File.join(source, "file1") - s2 = File.join(source, "file2") - d1 = File.join(dest, "file1") - d2 = File.join(dest, "file2") - Dir.mkdir(source) - [s1, s2].each { |name| File.open(name, "w") { |file| file.puts "something" } } - - # We have to add a second parameter, because that's the only way to expose the "bug". - file = Puppet::Type.newfile(:path => dest, :source => source, :recurse => true, :purge => true, :mode => "755") - - assert_apply(file) - - assert(FileTest.exists?(d1), "File1 was not copied") - assert(FileTest.exists?(d2), "File2 was not copied") - - File.unlink(s2) - - assert_apply(file) - - assert(FileTest.exists?(d1), "File1 was not kept") - assert(! FileTest.exists?(d2), "File2 was not purged") - end -end - diff --git a/test/ral/type/host.rb b/test/ral/type/host.rb deleted file mode 100755 index 00e1d9ef6..000000000 --- a/test/ral/type/host.rb +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'test/unit' -require 'facter' - -class TestHost < Test::Unit::TestCase - include PuppetTest - - def setup - super - @hosttype = Puppet::Type.type(:host) - - @provider = @hosttype.defaultprovider - - # Make sure they are using the parsed provider - unless @provider.name == :parsed - @hosttype.defaultprovider = @hosttype.provider(:parsed) - end - - cleanup do @hosttype.defaultprovider = nil end - - if @provider.respond_to?(:default_target=) - @default_file = @provider.default_target - cleanup do - @provider.default_target = @default_file - end - @target = tempfile - @provider.default_target = @target - end - end - - def mkhost - if defined?(@hcount) - @hcount += 1 - else - @hcount = 1 - end - - @catalog ||= mk_catalog - - host = nil - assert_nothing_raised { - - host = Puppet::Type.type(:host).new( - - :name => "fakehost#{@hcount}", - :ip => "192.168.27.#{@hcount}", - :alias => "alias#{@hcount}", - - :catalog => @catalog - ) - } - - host - end - - def test_list - list = nil - assert_nothing_raised do - list = @hosttype.defaultprovider.instances - end - - assert_equal(0, list.length, "Found hosts in empty file somehow") - end - - - def test_simplehost - host = nil - - assert_nothing_raised { - - host = Puppet::Type.type(:host).new( - - :name => "culain", - - :ip => "192.168.0.3" - ) - } - - current_values = nil - assert_nothing_raised { current_values = host.retrieve } - assert_events([:host_created], host) - - assert_nothing_raised { current_values = host.retrieve } - - assert_equal(:present, current_values[host.property(:ensure)]) - - host[:ensure] = :absent - - assert_events([:host_removed], host) - - assert_nothing_raised { current_values = host.retrieve } - - assert_equal(:absent, current_values[host.property(:ensure)]) - end - - def test_moddinghost - host = mkhost - cleanup do - host[:ensure] = :absent - assert_apply(host) - end - - assert_events([:host_created], host) - - current_values = nil - assert_nothing_raised { - current_values = host.retrieve - } - - # This was a hard bug to track down. - assert_instance_of(String, current_values[host.property(:ip)]) - - host[:ensure] = :absent - assert_events([:host_removed], host) - end - - def test_invalid_ipaddress - host = mkhost - - assert_raise(Puppet::Error) { - host[:ip] = "abc.def.ghi.jkl" - } - end - - def test_invalid_hostname - host = mkhost - - assert_raise(Puppet::Error) { - host[:name] = "!invalid.hostname.$PID$" - } - - assert_raise(Puppet::Error) { - host[:name] = "-boo" - } - - assert_raise(Puppet::Error) { - host[:name] = "boo-.ness" - } - - assert_raise(Puppet::Error) { - host[:name] = "boo..ness" - } - end - - def test_valid_hostname - host = mkhost - - assert_nothing_raised { - host[:name] = "yayness" - } - - assert_nothing_raised { - host[:name] = "yay-ness" - } - - assert_nothing_raised { - host[:name] = "yay.ness" - } - - assert_nothing_raised { - host[:name] = "yay.ne-ss" - } - - assert_nothing_raised { - host[:name] = "y.ay-ne-ss.com" - } - - assert_nothing_raised { - host[:name] = "y4y.n3-ss" - } - - assert_nothing_raised { - host[:name] = "y" - } - end -end diff --git a/test/ral/type/mailalias.rb b/test/ral/type/mailalias.rb deleted file mode 100755 index 1c867ef1b..000000000 --- a/test/ral/type/mailalias.rb +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'mocha' - -class TestMailAlias < Test::Unit::TestCase - include PuppetTest - - def setup - super - @type = Puppet::Type.type(:mailalias) - - @provider = @type.defaultprovider - - # Make sure they are using the parsed provider - unless @provider.name == :aliases - @type.defaultprovider = @type.provider(:aliases) - end - - cleanup do @type.defaultprovider = nil end - - if @provider.respond_to?(:default_target=) - @default_file = @provider.default_target - cleanup do - @provider.default_target = @default_file - end - @target = tempfile - @provider.default_target = @target - end - end - - # This isn't much of a test, but then, it's not much of a type. - def test_recipient_arrays - resource = @type.new(:name => "luke", :recipient => "yay", :target => tempfile) - values = resource.retrieve_resource - assert_equal(:absent, values[:recipient]) - resource.property(:recipient).expects(:set).with(%w{yay}) - assert_nothing_raised("Could not sync mailalias") do - resource.property(:recipient).sync - end - end -end - diff --git a/test/ral/type/port.rb b/test/ral/type/port.rb deleted file mode 100755 index 1daee1474..000000000 --- a/test/ral/type/port.rb +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' - -#require 'facter' -# -#class TestPort < Test::Unit::TestCase -# include PuppetTest -# -# def setup -# super -# @porttype = Puppet::Type.type(:port) -# -# @provider = @porttype.defaultprovider -# -# # Make sure they are using the parsed provider -# unless @provider.name == :parsed -# @porttype.defaultprovider = @porttype.provider(:parsed) -# end -# -# cleanup do @porttype.defaultprovider = nil end -# -# if @provider.respond_to?(:default_target) -# oldpath = @provider.default_target -# cleanup do -# @provider.default_target = oldpath -# end -# @provider.default_target = tempfile -# end -# end -# -# def mkport -# port = nil -# -# if defined?(@pcount) -# @pcount += 1 -# else -# @pcount = 1 -# end -# assert_nothing_raised { -# port = Puppet::Type.type(:port).new( -# :name => "puppet#{@pcount}", -# :number => "813#{@pcount}", -# :protocols => "tcp", -# :description => "The port that Puppet runs on", -# :alias => "coolness#{@pcount}" -# ) -# } -# -# return port -# end -# -# def test_list -# assert_nothing_raised { -# Puppet::Type.type(:port).list -# } -# -# count = 0 -# @porttype.each do |h| -# count += 1 -# end -# -# assert_equal(0, count, "Found hosts in empty file somehow") -# -# dns = @porttype["domain"] -# assert(dns, "Did not retrieve dns service") -# end -# -# def test_simpleport -# host = nil -# -# port = mkport -# -# assert_apply(port) -# assert_nothing_raised { -# port.retrieve -# } -# -# assert(port.provider.exists?, "Port did not get created") -# end -# -# def test_moddingport -# port = nil -# port = mkport -# -# assert_events([:port_created], port) -# -# port.retrieve -# -# port[:protocols] = %w{tcp udp} -# -# assert_events([:port_changed], port) -# end -# -# def test_multivalues -# port = mkport -# assert_raise(Puppet::Error) { -# port[:protocols] = "udp tcp" -# } -# assert_raise(Puppet::Error) { -# port[:alias] = "puppetmasterd yayness" -# } -# end -# -# def test_removal -# port = mkport -# assert_nothing_raised { -# port[:ensure] = :present -# } -# assert_events([:port_created], port) -# assert_events([], port) -# -# assert(port.provider.exists?, "port was not created") -# assert_nothing_raised { -# port[:ensure] = :absent -# } -# -# assert_events([:port_removed], port) -# assert(! port.provider.exists?, "port was not removed") -# assert_events([], port) -# end -# -# def test_addingproperties -# port = mkport -# assert_events([:port_created], port) -# -# port.delete(:alias) -# assert(! port.property(:alias)) -# assert_events([:port_changed], port) -# -# assert_nothing_raised { -# port.retrieve -# } -# -# assert_equal(:present, port.is(:ensure)) -# -# assert_equal(:absent, port.is(:alias)) -# -# port[:alias] = "yaytest" -# assert_events([:port_changed], port) -# port.retrieve -# assert(port.property(:alias).is == ["yaytest"]) -# end -#end - diff --git a/test/ral/type/resources.rb b/test/ral/type/resources.rb deleted file mode 100755 index 21604ba8e..000000000 --- a/test/ral/type/resources.rb +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env ruby -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' - -class TestResources < Test::Unit::TestCase - include PuppetTest - - def add_purge_lister - # Now define the list method - class << @purgetype - def instances - $purgemembers.values - end - end - end - - def mk_purger(managed = false) - @purgenum ||= 0 - @purgenum += 1 - obj = @purgetype.create :name => "purger#{@purgenum}" - $purgemembers[obj[:name]] = obj - obj[:fake] = "testing" if managed - obj - end - - def mkpurgertype - # Create a purgeable type - $purgemembers = {} - @purgetype = Puppet::Type.newtype(:purgetest) do - newparam(:name, :namevar => true) {} - newproperty(:ensure) do - newvalue(:absent) do - $purgemembers[@parent[:name]] = @parent - end - newvalue(:present) do - $purgemembers.delete(@parent[:name]) - end - end - newproperty(:fake) do - def sync - :faked - end - end - end - cleanup do - Puppet::Type.rmtype(:purgetest) - end - end - - def setup - super - @type = Puppet::Type.type(:resources) - end - - # Part of #408. - def test_check - # First check a non-user - res = Puppet::Type.type(:resources).new :name => :package - assert_nil(res[:unless_system_user], "got bad default for package") - - - assert_nothing_raised { - assert(res.check("A String"), "String failed check") - assert(res.check(Puppet::Type.type(:file).new(:path => tempfile)), "File failed check") - assert(res.check(Puppet::Type.type(:user).new(:name => "yayness")), "User failed check in package") - } - - # Now create a user manager - res = Puppet::Type.type(:resources).new :name => :user - - # Make sure the default is 500 - assert_equal(500, res[:unless_system_user], "got bad default") - - # Now make sure root fails the test - @user = Puppet::Type.type(:user) - assert_nothing_raised { - assert(! res.check(@user.create(:name => "root")), "root passed check") - assert(! res.check(@user.create(:name => "nobody")), "nobody passed check") - } - - # Now find a user between 0 and the limit - low = high = nil - Etc.passwd { |entry| - if ! low and (entry.uid > 10 and entry.uid < 500) - low = entry.name - else - # We'll reset the limit, since we can't really guarantee that - # there are any users with uid > 500 - if ! high and entry.uid > 100 and ! res.system_users.include?(entry.name) - high = entry.name - break - end - end - } - - assert(! res.check(@user.create(:name => low)), "low user #{low} passed check") if low - if high - res[:unless_system_user] = 50 - assert(res.check(@user.create(:name => high)), "high user #{high} failed check") - end - end -end - diff --git a/test/ral/type/service.rb b/test/ral/type/service.rb deleted file mode 100755 index b7ae8dfd6..000000000 --- a/test/ral/type/service.rb +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'mocha' - -class TestServiceType < Test::Unit::TestCase - include PuppetTest - - # #199 - def test_no_refresh_when_starting - service = Puppet::Type.type(:service).new :name => "hopefully_this_isnt_in_the_process_table", - :ensure => :running, :provider => :base - - assert_equal :running, service.instance_eval('@parameters[:ensure]').should - assert_not_equal :running, service.instance_eval('@parameters[:ensure]').retrieve, "You have something called #{service.name} in your process table" - - # First make sure it does not refresh - service.provider.expects(:restart).never - - assert_nothing_raised do - service.refresh - end - end - - def test_refresh_normally - service = Puppet::Type.type(:service).new :name => "testing", - :ensure => :running, :provider => :base, :status => "cat /dev/null" - - service.provider.expects(:restart) - - assert_nothing_raised do - service.refresh - end - end -end - diff --git a/test/ral/type/sshkey.rb b/test/ral/type/sshkey.rb deleted file mode 100755 index 2bdc00877..000000000 --- a/test/ral/type/sshkey.rb +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'facter' - -class TestSSHKey < Test::Unit::TestCase - include PuppetTest - def setup - super - # god i'm lazy - @sshkeytype = Puppet::Type.type(:sshkey) - - @provider = @sshkeytype.defaultprovider - - # Make sure they are using the parsed provider - unless @provider.name == :parsed - @sshkeytype.defaultprovider = @sshkeytype.provider(:parsed) - end - - cleanup do @sshkeytype.defaultprovider = nil end - - if @provider.respond_to?(:default_target) - oldpath = @provider.default_target - cleanup do - @provider.default_target = oldpath - end - @provider.default_target = tempfile - end - end - - def teardown - super - @provider.clear if @provider.respond_to?(:clear) - end - - def mkkey - key = nil - - if defined?(@kcount) - @kcount += 1 - else - @kcount = 1 - end - - @catalog ||= mk_catalog - - - key = @sshkeytype.new( - - :name => "host#{@kcount}.madstop.com", - :key => "#{@kcount}AAAAB3NzaC1kc3MAAACBAMnhSiku76y3EGkNCDsUlvpO8tRgS9wL4Eh54WZfQ2lkxqfd2uT/RTT9igJYDtm/+UHuBRdNGpJYW1Nw2i2JUQgQEEuitx4QKALJrBotejGOAWxxVk6xsh9xA0OW8Q3ZfuX2DDitfeC8ZTCl4xodUMD8feLtP+zEf8hxaNamLlt/AAAAFQDYJyf3vMCWRLjTWnlxLtOyj/bFpwAAAIEAmRxxXb4jjbbui9GYlZAHK00689DZuX0EabHNTl2yGO5KKxGC6Esm7AtjBd+onfu4Rduxut3jdI8GyQCIW8WypwpJofCIyDbTUY4ql0AQUr3JpyVytpnMijlEyr41FfIb4tnDqnRWEsh2H7N7peW+8DWZHDFnYopYZJ9Yu4/jHRYAAACAERG50e6aRRb43biDr7Ab9NUCgM9bC0SQscI/xdlFjac0B/kSWJYTGVARWBDWug705hTnlitY9cLC5Ey/t/OYOjylTavTEfd/bh/8FkAYO+pWdW3hx6p97TBffK0b6nrc6OORT2uKySbbKOn0681nNQh4a6ueR3JRppNkRPnTk5c=", - :type => "ssh-dss", - :alias => ["192.168.0.#{@kcount}"], - - :catalog => @catalog - ) - - @catalog.add_resource(key) - - key - end - - def test_instances - list = nil - assert_nothing_raised { - list = Puppet::Type.type(:sshkey).instances - } - - count = 0 - list.each do |h| - count += 1 - end - - assert_equal(0, count, "Found sshkeys in empty file somehow") - end - - def test_simplekey - key = mkkey - file = tempfile - key[:target] = file - key[:provider] = :parsed - - assert_apply(key) - - assert_events([], key, "created events on in-sync key") - - assert(key.provider.exists?, "Key did not get created") - - # Now create a new key object - name = key.name - key = nil - - key = @sshkeytype.new :name => name, :target => file, :provider => :parsed - key.retrieve - - assert(key.provider.exists?, "key thinks it does not exist") - - end - - def test_removal - sshkey = mkkey - assert_nothing_raised { - sshkey[:ensure] = :present - } - assert_events([:sshkey_created], sshkey) - - assert(sshkey.provider.exists?, "key was not created") - assert_nothing_raised { - sshkey[:ensure] = :absent - } - - assert_events([:sshkey_removed], sshkey) - assert(! sshkey.provider.exists?, "Key was not deleted") - assert_events([], sshkey) - end - - # Make sure changes actually modify the file. - def test_modifyingfile - keys = [] - names = [] - 3.times { - k = mkkey - #h[:ensure] = :present - #h.retrieve - keys << k - names << k.name - } - assert_apply(*keys) - keys.clear - - @catalog.clear(true) - @catalog = nil - - newkey = mkkey - #newkey[:ensure] = :present - names << newkey.name - assert_apply(newkey) - - # Verify we can retrieve that info - assert_nothing_raised("Could not retrieve after second write") { - newkey.provider.prefetch - } - - assert(newkey.provider.exists?, "Did not see key in file") - end -end diff --git a/test/ral/type/user.rb b/test/ral/type/user.rb deleted file mode 100755 index 404d84f4e..000000000 --- a/test/ral/type/user.rb +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'etc' - -class TestUser < Test::Unit::TestCase - include PuppetTest - - p = Puppet::Type.type(:user).provide :fake, :parent => PuppetTest::FakeProvider do - @name = :fake - apimethods - def create - @ensure = :present - @resource.send(:properties).each do |property| - next if property.name == :ensure - property.sync - end - end - - def delete - @ensure = :absent - @resource.send(:properties).each do |property| - send(property.name.to_s + "=", :absent) - end - end - - def exists? - if @ensure == :present - true - else - false - end - end - end - - FakeUserProvider = p - - @@fakeproviders[:group] = p - - def findshell(old = nil) - %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh - /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh - /usr/bin/tcsh}.find { |shell| - if old - FileTest.exists?(shell) and shell != old - else - FileTest.exists?(shell) - end - } - end - - def setup - super - Puppet::Type.type(:user).defaultprovider = FakeUserProvider - end - - def teardown - Puppet::Type.type(:user).defaultprovider = nil - super - end - - def mkuser(name) - user = nil - assert_nothing_raised { - - user = Puppet::Type.type(:user).new( - - :name => name, - :comment => "Puppet Testing User", - :gid => Puppet::Util::SUIDManager.gid, - :shell => findshell, - - :home => "/home/#{name}" - ) - } - - assert(user, "Did not create user") - - user - end - - def test_autorequire - file = tempfile - comp = nil - user = nil - group =nil - home = nil - ogroup = nil - assert_nothing_raised { - - user = Puppet::Type.type(:user).new( - - :name => "pptestu", - :home => file, - :gid => "pptestg", - - :groups => "yayness" - ) - - home = Puppet::Type.type(:file).new( - - :path => file, - :owner => "pptestu", - - :ensure => "directory" - ) - group = Puppet::Type.type(:group).new( - :name => "pptestg" - ) - ogroup = Puppet::Type.type(:group).new( - :name => "yayness" - ) - comp = mk_catalog(user, group, home, ogroup) - } - - rels = nil - assert_nothing_raised { rels = user.autorequire } - - assert(rels.detect { |r| r.source == group }, "User did not require group") - assert(rels.detect { |r| r.source == ogroup }, "User did not require other groups") - assert_nothing_raised { rels = home.autorequire } - assert(rels.detect { |r| r.source == user }, "Homedir did not require user") - end - - # Testing #455 - def test_autorequire_with_no_group_should - user = Puppet::Type.type(:user).new(:name => "yaytest", :check => :all) - catalog = mk_catalog(user) - - assert_nothing_raised do - user.autorequire - end - - user[:ensure] = :absent - - assert(user.property(:groups).insync?(nil), - "Groups state considered out of sync with no :should value") - end - - # Make sure the 'managehome' param can only be set when the provider - # has that feature. Uses a patch from #432. - def test_managehome - user = Puppet::Type.type(:user).new(:name => "yaytest", :check => :all) - - prov = user.provider - - home = false - prov.class.meta_def(:manages_homedir?) { home } - - assert_nothing_raised("failed on false managehome") do - user[:managehome] = false - end - - assert_raise(Puppet::Error, "did not fail when managehome? is false") do - user[:managehome] = true - end - - home = true - assert(prov.class.manages_homedir?, "provider did not enable homedir") - assert_nothing_raised("failed when managehome is true") do - user[:managehome] = true - end - end -end - diff --git a/test/ral/type/zone.rb b/test/ral/type/zone.rb deleted file mode 100755 index c93cc68bc..000000000 --- a/test/ral/type/zone.rb +++ /dev/null @@ -1,447 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../../lib/puppettest') - -require 'puppettest' -require 'puppet/type/zone' - -class TestZone < PuppetTest::TestCase - confine "Zones are only functional on Solaris" => (Facter["operatingsystem"].value == "Solaris") - - def setup - super - @@zones = [] - end - - def mkzone(name) - zone = nil - - base = tempfile - Dir.mkdir(base) - File.chmod(0700, base) - root = File.join(base, "zonebase") - assert_nothing_raised { - - zone = Puppet::Type.type(:zone).new( - - :name => name, - :path => root, - - :ensure => "configured" # don't want to install zones automatically - ) - } - - @@zones << name - - zone - end - - def test_instances - list = nil - assert_nothing_raised { - list = Puppet::Type.type(:zone).instances - } - - assert(! list.empty?, "Got no zones back") - - assert(list.find { |z| z[:name] == "global" }, "Could not find global zone") - end - - def test_state_sequence - zone = mkzone("slicetest") - - property = zone.property(:ensure) - - slice = nil - assert_nothing_raised { - slice = property.class.state_sequence(:absent, :installed).collect do |o| - o[:name] - end - } - - - assert_equal([:configured, :installed], slice) - - assert_nothing_raised { - slice = property.class.state_sequence(:running, :installed).collect do |o| - o[:name] - end - } - - - assert_equal(slice, [:installed]) - - end - - # Make sure the ensure stuff behaves as we expect - def test_zoneensure - zone = mkzone("ensurezone") - - property = zone.property(:ensure) - - assert(property, "Did not get ensure property") - - values = nil - assert_nothing_raised { - values = zone.retrieve - } - - assert(! property.insync?(values[property]), "Property is somehow in sync") - - assert(property.up?, "Property incorrectly thinks it is not moving up") - - zone[:ensure] = :installed - assert(property.up?, "Property incorrectly thinks it is not moving up") - zone[:ensure] = :absent - assert(! property.up?, "Property incorrectly thinks it is moving up") - end - - # Make sure all mentioned methods actually exist. - def test_zonemethods_exist - methods = [] - zone = mkzone("methodtest") - - property = zone.property(:ensure) - assert_nothing_raised { - property.class.state_sequence(:absent, :running).each do |st| - [:up, :down].each do |m| - methods << st[m] if st[m] - end - end - } - - methods.each do |m| - Puppet::Type.type(:zone).suitableprovider.each do |prov| - - assert( - prov.method_defined?(m), - - "Zone provider #{prov.name} does not define method #{m}") - end - end - - end - - # Make sure our property generates the correct text. - def test_inherit_property - zone = mkzone("configtesting") - zone[:ensure] = :configured - - assert_nothing_raised { - zone[:inherit] = "/usr" - } - property = zone.property(:inherit) - assert(zone, "Did not get 'inherit' property") - - - assert_equal( - "add inherit-pkg-dir\nset dir=/usr\nend", property.configtext, - - "Got incorrect config text") - - zone.provider.inherit = "/usr" - - - assert_equal( - "", property.configtext, - - "Got incorrect config text") - - # Now we want multiple directories - property.should = %w{/usr /sbin /lib} - - # The statements are sorted - text = "add inherit-pkg-dir -set dir=/lib -end -add inherit-pkg-dir -set dir=/sbin -end" - - - assert_equal( - text, property.configtext, - - "Got incorrect config text") - - zone.provider.inherit = %w{/usr /sbin /lib} - property.should = %w{/usr /sbin} - - text = "remove inherit-pkg-dir dir=/lib" - - - assert_equal( - text, property.configtext, - - "Got incorrect config text") - end -end - -class TestZoneAsRoot < TestZone - confine "Not running Zone creation tests" => Puppet.features.root? - confine "Zones are only functional on Solaris" => (Facter["operatingsystem"].value == "Solaris") - - def teardown - current = %x{zoneadm list -cp}.split("\n").inject({}) { |h, line| - ary = line.split(":") - h[ary[1]] = ary[2] - h - } - - # Get rid of any lingering zones - @@zones.each do |zone| - next unless current.include? zone - - obj = Puppet::Type.type(:zone).new(:name => zone) - obj[:ensure] = :absent - assert_apply(obj) - end - - # We can't delete the temp files until the zones are stopped and removed. - super - end - # Make sure our ensure process actually works. - def test_ensure_sync - zone = mkzone("ensuretesting") - - zone[:ensure] = :configured - - assert_apply(zone) - - assert(zone.insync?(zone.retrieve), "Zone is not insync") - end - - def test_getconfig - zone = mkzone("configtesting") - - base = tempfile - zone[:path] = base - - ip = "192.168.0.1" - interface = "bge0" - zone[:ip] = "#{interface}:#{ip}" - - IO.popen("zonecfg -z configtesting -f -", "w") do |f| - f.puts %{create -b -set zonepath=#{tempfile} -set autoboot=true -add inherit-pkg-dir -set dir=/lib -end -add inherit-pkg-dir -set dir=/platform -end -add inherit-pkg-dir -set dir=/sbin -end -add inherit-pkg-dir -set dir=/opt/csw -end -add inherit-pkg-dir -set dir=/usr -end -add net -set address=#{ip} -set physical=bge0 -end -} - end - - assert_equal(0, $CHILD_STATUS, "Did not successfully create zone") - - hash = nil - assert_nothing_raised { - hash = zone.provider.send(:getconfig) - } - - zone[:check] = [:inherit, :autoboot] - - values = nil - assert_nothing_raised("Could not retrieve zone values") do - values = zone.retrieve.inject({}) { |result, newvals| result[newvals[0].name] = newvals[1]; result } - end - - # And make sure it gets set correctly. - - assert_equal( - %w{/sbin /usr /opt/csw /lib /platform}.sort, - - values[:inherit].sort, "Inherited dirs did not get collected correctly." - ) - - - assert_equal( - ["#{interface}:#{ip}"], values[:ip], - - "IP addresses did not get collected correctly.") - - - assert_equal( - :true, values[:autoboot], - - "Autoboot did not get collected correctly.") - end - - # Make sure we can do all the various and sundry configuring things. - def test_configuring_zones - zone = mkzone("configtesting") - - assert_nothing_raised { - zone[:inherit] = "/usr" - } - - zone[:ensure] = :configured - - assert_apply(zone) - - assert(zone.insync?(zone.retrieve), "Zone is not insync") - - # Now add a new directory to inherit - assert_nothing_raised { - zone[:inherit] = ["/sbin", "/usr"] - } - assert_apply(zone) - - assert(zone.insync?(zone.retrieve), "Zone is not insync") - - - assert( - %x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /dir: \/sbin/, - - "sbin was not added") - - # And then remove it. - assert_nothing_raised { - zone[:inherit] = "/usr" - } - assert_apply(zone) - - assert(zone.insync?(zone.retrieve), "Zone is not insync") - - - assert( - %x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /dir: \/sbin/, - - "sbin was not removed") - - # Now add an ip adddress. Fortunately (or not), zonecfg doesn't verify - # that the interface exists. - zone[:ip] = "hme0:192.168.0.1" - - assert(! zone.insync?(zone.retrieve), "Zone is marked as in sync") - - assert_apply(zone) - assert(zone.insync?(zone.retrieve), "Zone is not in sync") - - assert( - %x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.1/, - - "ip was not added") - zone[:ip] = ["hme1:192.168.0.2", "hme0:192.168.0.1"] - assert_apply(zone) - assert(zone.insync?(zone.retrieve), "Zone is not in sync") - assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.2/, "ip was not added") - zone[:ip] = ["hme1:192.168.0.2"] - assert_apply(zone) - zone.retrieve - assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /192.168.0.1/, "ip was not removed") - end - - # Test creating and removing a zone, but only up to the configured property, - # so it's faster. - def test_smallcreate - zone = mkzone("smallcreate") - # Include a bunch of stuff so the zone isn't as large - dirs = %w{/usr /sbin /lib /platform} - - %w{/opt/csw}.each do |dir| - dirs << dir if FileTest.exists? dir - end - zone[:inherit] = dirs - - assert(zone, "Did not make zone") - - zone[:ensure] = :configured - - assert(! zone.insync?(zone.retrieve), "Zone is incorrectly in sync") - - assert_apply(zone) - - assert(zone.insync?(zone.retrieve), "Zone is incorrectly out of sync") - - zone[:ensure] = :absent - - assert_apply(zone) - - currentvalues = zone.retrieve - - assert_equal(:absent, currentvalues[zone.property(:ensure)], - "Zone is not absent") - end - - # Just go through each method linearly and make sure it works. - def test_each_method - zone = mkzone("methodtesting") - dirs = %w{/usr /sbin /lib /platform} - - %w{/opt/csw}.each do |dir| - dirs << dir if FileTest.exists? dir - end - zone[:inherit] = dirs - - [[:configure, :configured], - [:install, :installed], - [:start, :running], - [:stop, :installed], - [:uninstall, :configured], - [:unconfigure, :absent] - ].each do |method, property| - Puppet.info "Testing #{method}" - current_values = nil - assert_nothing_raised { - current_values = zone.retrieve - } - assert_nothing_raised { - zone.provider.send(method) - } - current_values = nil - assert_nothing_raised { - current_values = zone.retrieve - } - assert_equal(property, current_values[zone.property(:ensure)], "Method #{method} did not correctly set property #{property}") - end - end - - def test_mkzone - zone = mkzone("testmaking") - # Include a bunch of stuff so the zone isn't as large - dirs = %w{/usr /sbin /lib /platform} - - %w{/opt/csw}.each do |dir| - dirs << dir if FileTest.exists? dir - end - zone[:inherit] = dirs - - assert(zone, "Did not make zone") - - - [:configured, :installed, :running, :installed, :absent].each do |value| - assert_nothing_raised { - zone[:ensure] = value - } - assert(! zone.insync?(zone.retrieve), "Zone is incorrectly in sync") - - assert_apply(zone) - - assert_nothing_raised { - assert(zone.insync?(zone.retrieve), "Zone is incorrectly out of sync") - } - end - - currentvalues = zone.retrieve - - assert_equal(:absent, currentvalues[zone.property(:ensure)], - "Zone is not absent") - end -end - diff --git a/test/test b/test/test deleted file mode 100755 index 8d2659cb7..000000000 --- a/test/test +++ /dev/null @@ -1,241 +0,0 @@ -#!/usr/bin/env ruby - -# -# = Synopsis -# -# Run unit tests, usually with the goal of resolving some conflict -# between tests. -# -# = Usage -# -# test [-d|--debug] [-f|--files] [-h|--help] [-n method] [-v|--verbose] [file] ... -# -# = Description -# -# This script is useful for running a specific subset of unit tests, especially -# when attempting to find a conflict between tests. By default, it will take -# the first argument you pass it and run that test or test directory with each -# test directory in turn, looking for a failure. If any tests fail, then -# the script will drill into that test directory, looking for the specific conflict. -# -# In this way, when you have deduced you have two conflicting unit tests (tests which -# pass in isolation but fail when run together), you can tell this script where -# the failure is and leave it alone to find the conflict. -# -# This script is different from the Rakefile because it will run all tests in -# a single process, whereas if you ask the Rakefile to run multiple tests, it will -# run them in separate processes thus making it impossible to find conflicts. -# -# = Examples -# -# Attempt to resolve a conflict between a single test suite that could be anywhere: -# -# ./test ral/providers/user.rb -# -# Determine whether two individual files conflict: -# -# ./test --files language/functions.rb ral/providers/provider.rb -# -# Run the same test, but only run a specific unit test: -# -# ./test -d -n test_search --files language/functions.rb ral/providers/provider.rb -# -# = Options -# -# debug:: -# Enable full debugging. -# -# files:: -# Specify exactly which files to test. -# -# help:: -# Print this help message -# -# n:: -# Specify a single unit test to run. You can still specify as many files -# as you want. -# -# verbose:: -# Print extra information. -# -# = Example -# -# puppet -l /tmp/script.log script.pp -# -# = Author -# -# Luke Kanies -# -# = Copyright -# -# Copyright (c) 2005-2011 Puppet Labs, LLC -# Licensed under the Apache 2.0 License - -require 'find' -require 'getoptlong' -include Find - -result = GetoptLong.new( - [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], - [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], - [ "-n", GetoptLong::REQUIRED_ARGUMENT ], - [ "--files", "-f", GetoptLong::NO_ARGUMENT ], - [ "--help", "-h", GetoptLong::NO_ARGUMENT ] -) - -usage = "USAGE: %s [--help] suite" % $0 - -$options = {} -keep = [] - -result.each { |opt,arg| - case opt - when "--verbose" - $options[:verbose] = true - when "--files" - $options[:files] = true - when "--debug" - $options[:debug] = true - $options[:verbose] = true - when "--help" - puts usage - exit - else - keep << opt - keep << arg if arg - end -} - -def dirs - Dir.glob("*").find_all { |d| FileTest.directory?(d) }.reject { |d| - ["lib", "data"].include?(d) - } -end - -def rake(*args) - print "trying %s..." % args.join(" ") - output = %x{rake %s} % args.join(" ") - - if $?.exitstatus == 0 - puts "succeeded" - return true - else - puts "failed" - return false - end -end - -def resolve(dir) - dirs = dirs() - - # If the passed dir is a subdir or file, put the basedir last - if dir.include?(File::SEPARATOR) - basedir = dir.split(File::SEPARATOR)[0] - if dirs.include?(basedir) - dirs.delete(basedir) - dirs << basedir - end - end - - failed = nil - dirs.each do |d| - next if d == dir - unless run([d, dir]) - failed = d - break - end - end - puts "%s failed" % failed - - files = ruby_files(failed) - - files.each do |file| - unless run([file, dir]) - puts file - exit(0) - end - end - - exit(1) -end - -def ruby_files(dir) - files = [] - # First collect the entire file list. - begin - find(dir) { |f| files << f if f =~ /\.rb$/ } - rescue => detail - puts "could not find on %s: %s" % [dir.inspect, detail] - end - files -end - -def run(files, flags = nil) - args = %w{ruby} - args << "-Ilib:../lib" - args << "lib/rake/puppet_test_loader.rb" - if flags - args += flags - end - args += ARGV - - print files.join(" ") + "... " - $stdout.flush - - files.each do |file| - case File.stat(file).ftype - when "file"; args << file - when "directory"; args += ruby_files(file) - else - $stderr.puts "Skipping %s; can't handle %s" % - [file, File.stat(file).ftype] - end - end - args = args.join(" ") - if $options[:verbose] - p args - end - output = %x{#{args} 2>&1} - if $options[:debug] - print output - end - - if $?.exitstatus == 0 - puts "succeeded" - return true - else - puts "failed" - puts output - return false - end -end - -if $options[:files] - run(ARGV, keep) -else - dir = ARGV.shift - - unless dir - $stderr.puts usage - exit(1) - end - resolve(dir) -end -# -# -#files = [] -# -#args.each do |test| -# if FileTest.directory?(test) -# files += ruby_files(test) -# end -#end - -## Now load all of our files. -#files.each do |file| -# load file unless file =~ /^-/ -#end -# -#runner = Test::Unit::AutoRunner.new(false) -#runner.process_args -#runner.run diff --git a/test/util/classgen.rb b/test/util/classgen.rb deleted file mode 100755 index aa9bdbed7..000000000 --- a/test/util/classgen.rb +++ /dev/null @@ -1,241 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppettest' - -class TestPuppetUtilClassGen < Test::Unit::TestCase - include PuppetTest - - class FakeBase - class << self - attr_accessor :name - end - end - - class GenTest - class << self - include Puppet::Util::ClassGen - end - end - - def testclasses(name) - sub = Class.new(GenTest) do @name = "base#{name.to_s}" end - self.class.const_set("Base#{name.to_s}", sub) - - klass = Class.new(FakeBase) do @name = "gen#{name.to_s}"end - - return sub, klass - end - - def test_handleclassconst - sub, klass = testclasses("const") - const = nil - assert_nothing_raised do - const = sub.send(:handleclassconst, klass, klass.name, {}) - end - - # make sure the constant is set - assert(defined?(Baseconst::Genconst), "const was not defined") - assert_equal(Baseconst::Genconst.object_id, klass.object_id) - - # Now make sure don't replace by default - newklass = Class.new(FakeBase) do @name = klass.name end - assert_raise(Puppet::ConstantAlreadyDefined) do - const = sub.send(:handleclassconst, newklass, klass.name, {}) - end - assert_equal(Baseconst::Genconst.object_id, klass.object_id) - - # Now make sure we can replace it - assert_nothing_raised do - const = sub.send(:handleclassconst, newklass, klass.name, :overwrite => true) - end - assert_equal(Baseconst::Genconst.object_id, newklass.object_id) - - # Now make sure we can choose our own constant - assert_nothing_raised do - - const = sub.send( - :handleclassconst, newklass, klass.name, - - :constant => "Fooness") - end - assert(defined?(Baseconst::Fooness), "Specified constant was not defined") - - # And make sure prefixes work - assert_nothing_raised do - - const = sub.send( - :handleclassconst, newklass, klass.name, - - :prefix => "Test") - end - assert(defined?(Baseconst::TestGenconst), "prefix was not used") - end - - def test_initclass_preinit - sub, klass = testclasses("preinit") - - class << klass - attr_accessor :set - def preinit - @set = true - end - end - - assert(!klass.set, "Class was already initialized") - - assert_nothing_raised do sub.send(:initclass, klass, {}) end - - assert(klass.set, "Class was not initialized") - end - - def test_initclass_initvars - sub, klass = testclasses("initvars") - - class << klass - attr_accessor :set - def initvars - @set = true - end - end - - assert(!klass.set, "Class was already initialized") - - assert_nothing_raised do sub.send(:initclass, klass, {}) end - - assert(klass.set, "Class was not initialized") - end - - def test_initclass_attributes - sub, klass = testclasses("attributes") - - class << klass - attr_accessor :one, :two, :three - end - - assert(!klass.one, "'one' was already set") - - - assert_nothing_raised do sub.send( - :initclass, klass, - - :attributes => {:one => :a, :two => :b}) end - - assert_equal(:a, klass.one, "Class was initialized incorrectly") - assert_equal(:b, klass.two, "Class was initialized incorrectly") - assert_nil(klass.three, "Class was initialized incorrectly") - end - - def test_initclass_include_and_extend - sub, klass = testclasses("include_and_extend") - - incl = Module.new do - attr_accessor :included - end - self.class.const_set("Incl", incl) - - ext = Module.new do - attr_accessor :extended - end - self.class.const_set("Ext", ext) - - assert(! klass.respond_to?(:extended), "Class already responds to extended") - assert(! klass.new.respond_to?(:included), "Class already responds to included") - - - assert_nothing_raised do sub.send( - :initclass, klass, - - :include => incl, :extend => ext) - end - - assert(klass.respond_to?(:extended), "Class did not get extended") - assert(klass.new.respond_to?(:included), "Class did not include") - end - - def test_genclass - hash = {} - array = [] - - name = "yayness" - klass = nil - assert_nothing_raised { - klass = GenTest.genclass(name, :array => array, :hash => hash, :parent => FakeBase) do - class << self - attr_accessor :name - end - end - } - - assert(klass.respond_to?(:name=), "Class did not execute block") - - - assert( - hash.include?(klass.name), - - "Class did not get added to hash") - - assert( - array.include?(klass), - - "Class did not get added to array") - assert_equal(klass.superclass, FakeBase, "Parent class was wrong") - end - - # Make sure we call a preinithook, if there is one. - def test_inithooks - newclass = Class.new(FakeBase) do - class << self - attr_accessor :preinited, :postinited - end - def self.preinit - self.preinited = true - end - def self.postinit - self.postinited = true - end - end - - klass = nil - assert_nothing_raised { - klass = GenTest.genclass(:funtest, :parent => newclass) - } - - assert(klass.preinited, "prehook did not get called") - assert(klass.postinited, "posthook did not get called") - end - - def test_modulegen - hash = {} - array = [] - - name = "modness" - mod = nil - assert_nothing_raised { - mod = GenTest.genmodule(name, :array => array, :hash => hash) do - class << self - attr_accessor :yaytest - end - - @yaytest = true - end - } - - assert(mod.respond_to?(:yaytest), "Class did not execute block") - - assert_instance_of(Module, mod) - assert(hash.include?(mod.name), "Class did not get added to hash") - assert(array.include?(mod), "Class did not get added to array") - end - - def test_genconst_string - const = nil - assert_nothing_raised do - const = GenTest.send(:genconst_string, :testing, :prefix => "Yayness") - end - assert_equal("YaynessTesting", const) - end -end - diff --git a/test/util/fileparsing.rb b/test/util/fileparsing.rb deleted file mode 100755 index 831f19bdb..000000000 --- a/test/util/fileparsing.rb +++ /dev/null @@ -1,725 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'puppettest/fileparsing' -require 'puppet' -require 'puppet/util/fileparsing' - -class TestUtilFileParsing < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - class FParser - include Puppet::Util::FileParsing - end - - def setup - super - @parser = FParser.new - end - - def test_lines - assert_equal("\n", @parser.line_separator, "Default separator was incorrect") - - {"\n" => ["one two\nthree four", "one two\nthree four\n"], - "\t" => ["one two\tthree four", "one two\tthree four\t"], - }.each do |sep, tests| - assert_nothing_raised do - @parser.line_separator = sep - end - - assert_equal( - sep, @parser.line_separator, - - "Did not set separator") - - tests.each do |test| - assert_equal(["one two", "three four"], @parser.lines(test), "Incorrectly parsed #{test.inspect}") - end - end - end - - # Make sure parse calls the appropriate methods or errors out - def test_parse - @parser.meta_def(:parse_line) do |line| - line.split(/\s+/) - end - - text = "one line\ntwo line" - should = [%w{one line}, %w{two line}] - ret = nil - assert_nothing_raised do - ret = @parser.parse(text) - end - - assert_equal(should, ret) - end - - # Make sure we correctly handle different kinds of text lines. - def test_text_line - comment = "# this is a comment" - - # Make sure it fails if no regex is passed - assert_raise(ArgumentError) do - @parser.text_line :comment - end - - # define a text matching comment record - assert_nothing_raised do - @parser.text_line :comment, :match => /^#/ - end - - # Make sure it matches - assert_nothing_raised do - - assert_equal( - {:record_type => :comment, :line => comment}, - - @parser.parse_line(comment)) - end - - # But not something else - assert_nothing_raised do - assert_nil(@parser.parse_line("some other text")) - end - - # Now define another type and make sure we get the right one back - assert_nothing_raised do - @parser.text_line :blank, :match => /^\s*$/ - end - - # The comment should still match - assert_nothing_raised do - - assert_equal( - {:record_type => :comment, :line => comment}, - - @parser.parse_line(comment)) - end - - # As should our new line type - assert_nothing_raised do - - assert_equal( - {:record_type => :blank, :line => ""}, - - @parser.parse_line("")) - end - - end - - def test_parse_line - Puppet[:trace] = false - - comment = "# this is a comment" - - # Make sure it fails if we don't have any record types defined - assert_raise(Puppet::DevError) do - @parser.parse_line(comment) - end - - # Now define a text matching comment record - assert_nothing_raised do - @parser.text_line :comment, :match => /^#/ - end - - # And make sure we can't define another one with the same name - assert_raise(ArgumentError) do - @parser.text_line :comment, :match => /^"/ - end - - result = nil - assert_nothing_raised("Did not parse text line") do - result = @parser.parse_line comment - end - - assert_equal({:record_type => :comment, :line => comment}, result) - - # Make sure we just return nil on unmatched lines. - assert_nothing_raised("Did not parse text line") do - result = @parser.parse_line "No match for this" - end - - assert_nil(result, "Somehow matched an empty line") - - # Now define another type of comment, and make sure both types get - # correctly returned as comments - assert_nothing_raised do - @parser.text_line :comment2, :match => /^"/ - end - - assert_nothing_raised("Did not parse old comment") do - assert_equal({:record_type => :comment, :line => comment}, @parser.parse_line(comment)) - end - comment = '" another type of comment' - assert_nothing_raised("Did not parse new comment") do - assert_equal({:record_type => :comment2, :line => comment}, @parser.parse_line(comment)) - end - - # Now define two overlapping record types and make sure we keep the - # correct order. We do first match, not longest match. - assert_nothing_raised do - @parser.text_line :one, :match => /^y/ - @parser.text_line :two, :match => /^yay/ - end - - assert_nothing_raised do - assert_equal({:record_type => :one, :line => "yayness"}, @parser.parse_line("yayness")) - end - - end - - def test_record_line - tabrecord = "tab separated content" - spacerecord = "space separated content" - - # Make sure we always require an appropriate set of options - [{:separator => "\t"}, {}, {:fields => %w{record_type}}].each do |opts| - assert_raise(ArgumentError, "Accepted #{opts.inspect}") do - @parser.record_line :record, opts - end - end - - # Verify that our default separator is tabs - tabs = nil - assert_nothing_raised do - tabs = @parser.record_line :tabs, :fields => [:name, :first, :second] - end - - # Make sure out tab line gets matched - tabshould = {:record_type => :tabs, :name => "tab", :first => "separated", :second => "content"} - assert_nothing_raised do - assert_equal(tabshould, @parser.handle_record_line(tabrecord, tabs)) - end - - # Now add our space-separated record type - spaces = nil - assert_nothing_raised do - spaces = @parser.record_line :spaces, :fields => [:name, :first, :second] - end - - # Now make sure both lines parse correctly - spaceshould = {:record_type => :spaces, :name => "space", :first => "separated", :second => "content"} - - assert_nothing_raised do - assert_equal(tabshould, @parser.handle_record_line(tabrecord, tabs)) - assert_equal(spaceshould, @parser.handle_record_line(spacerecord, spaces)) - end - end - - def test_to_line - @parser.text_line :comment, :match => /^#/ - @parser.text_line :blank, :match => /^\s*$/ - @parser.record_line :record, :fields => %w{name one two}, :joiner => "\t" - - johnny = {:record_type => :record, :name => "johnny", :one => "home", - :two => "yay"} - bill = {:record_type => :record, :name => "bill", :one => "work", - :two => "boo"} - - records = { - :comment => {:record_type => :comment, :line => "# This is a file"}, - :blank => {:record_type => :blank, :line => ""}, - :johnny => johnny, - :bill => bill - } - - lines = { - :comment => "# This is a file", - :blank => "", - :johnny => "johnny home yay", - :bill => "bill work boo" - } - - records.each do |name, details| - result = nil - assert_nothing_raised do - result = @parser.to_line(details) - end - - assert_equal(lines[name], result) - end - order = [:comment, :blank, :johnny, :bill] - - file = order.collect { |name| lines[name] }.join("\n") - - ordered_records = order.collect { |name| records[name] } - - # Make sure we default to a trailing separator - assert_equal(true, @parser.trailing_separator, "Did not default to a trailing separtor") - - # Start without a trailing separator - @parser.trailing_separator = false - assert_nothing_raised do - assert_equal(file, @parser.to_file(ordered_records)) - end - - # Now with a trailing separator - file += "\n" - @parser.trailing_separator = true - assert_nothing_raised do - assert_equal(file, @parser.to_file(ordered_records)) - end - - # Now try it with a different separator, so we're not just catching - # defaults - file.gsub!("\n", "\t") - @parser.line_separator = "\t" - assert_nothing_raised do - assert_equal(file, @parser.to_file(ordered_records)) - end - end - - # Make sure fields that are marked absent get replaced with the appropriate - # string. - def test_absent_fields - record = nil - assert_nothing_raised do - record = @parser.record_line :record, :fields => %w{one two three}, - :optional => %w{two three} - end - assert_equal("", record.absent, "Did not set a default absent string") - - result = nil - assert_nothing_raised do - - result = @parser.to_line( - :record_type => :record, - - :one => "a", :two => :absent, :three => "b") - end - - assert_equal("a b", result, "Absent was not correctly replaced") - - # Now try using a different replacement character - record.absent = "*" # Because cron is a pain in my ass - assert_nothing_raised do - result = @parser.to_line(:record_type => :record, :one => "a", :two => :absent, :three => "b") - end - - assert_equal("a * b", result, "Absent was not correctly replaced") - - # Make sure we deal correctly with the string 'absent' - assert_nothing_raised do - - result = @parser.to_line( - :record_type => :record, - - :one => "a", :two => "b", :three => 'absent') - end - - assert_equal("a b absent", result, "Replaced string 'absent'") - - # And, of course, make sure we can swap things around. - assert_nothing_raised do - - result = @parser.to_line( - :record_type => :record, - - :one => "a", :two => "b", :three => :absent) - end - - assert_equal("a b *", result, "Absent was not correctly replaced") - end - - # Make sure we can specify a different join character than split character - def test_split_join_record_line - check = proc do |start, record, final| - # Check parsing first - result = @parser.parse_line(start) - [:one, :two].each do |param| - - assert_equal( - record[param], result[param], - - "Did not correctly parse #{start.inspect}") - end - - # And generating - assert_equal(final, @parser.to_line(result), "Did not correctly generate #{final.inspect} from #{record.inspect}") - end - - # First try it with symmetric characters - @parser.record_line :symmetric, :fields => %w{one two}, - :separator => " " - - check.call "a b", {:one => "a", :two => "b"}, "a b" - @parser.clear_records - - # Now assymetric but both strings - @parser.record_line :asymmetric, :fields => %w{one two}, - :separator => "\t", :joiner => " " - - check.call "a\tb", {:one => "a", :two => "b"}, "a b" - @parser.clear_records - - # And assymmetric with a regex - @parser.record_line :asymmetric2, :fields => %w{one two}, - :separator => /\s+/, :joiner => " " - - check.call "a\tb", {:one => "a", :two => "b"}, "a b" - check.call "a b", {:one => "a", :two => "b"}, "a b" - end - - # Make sure we correctly regenerate files. - def test_to_file - @parser.text_line :comment, :match => /^#/ - @parser.text_line :blank, :match => /^\s*$/ - @parser.record_line :record, :fields => %w{name one two} - - text = "# This is a comment - -johnny one two -billy three four\n" - -# Just parse and generate, to make sure it's isomorphic. -assert_nothing_raised do - assert_equal(text, @parser.to_file(@parser.parse(text)), - "parsing was not isomorphic") - end - end - - def test_valid_attrs - @parser.record_line :record, :fields => %w{one two three} - - - assert( - @parser.valid_attr?(:record, :one), - - "one was considered invalid") - - - assert( - @parser.valid_attr?(:record, :ensure), - - "ensure was considered invalid") - - - assert( - ! @parser.valid_attr?(:record, :four), - - "four was considered valid") - end - - def test_record_blocks - options = nil - assert_nothing_raised do - # Just do a simple test - options = @parser.record_line :record, - :fields => %w{name alias info} do |line| - line = line.dup - ret = {} - if line.sub!(/(\w+)\s*/, '') - ret[:name] = $1 - else - return nil - end - - if line.sub!(/(#.+)/, '') - desc = $1.sub(/^#\s*/, '') - ret[:description] = desc unless desc == "" - end - - ret[:alias] = line.split(/\s+/) if line != "" - - return ret - end - end - - values = { - :name => "tcpmux", - :description => "TCP port service multiplexer", - :alias => ["sink"] - } - - { - - "tcpmux " => [:name], - "tcpmux" => [:name], - "tcpmux sink" => [:name, :port, :protocols, :alias], - "tcpmux # TCP port service multiplexer" => - [:name, :description, :port, :protocols], - "tcpmux sink # TCP port service multiplexer" => - [:name, :description, :port, :alias, :protocols], - "tcpmux sink null # TCP port service multiplexer" => - [:name, :description, :port, :alias, :protocols], - }.each do |line, should| - result = nil - assert_nothing_raised do - result = @parser.handle_record_line(line, options) - end - assert(result, "Did not get a result back for '#{line}'") - should.each do |field| - if field == :alias and line =~ /null/ - assert_equal(%w{sink null}, result[field], "Field #{field} was not right in '#{line}'") - else - assert_equal(values[field], result[field], "Field #{field} was not right in '#{line}'") - end - end - end - - - end - - # Make sure we correctly handle optional fields. We'll skip this - # functionality until we really know we need it. - def test_optional_fields - assert_nothing_raised do - @parser.record_line :record, - :fields => %w{one two three four}, - :optional => %w{three four}, - :absent => "*", - :separator => " " # A single space - end - - { "a b c d" => [], - "a b * d" => [:three], - "a b * *" => [:three, :four], - "a b c *" => [:four] - }.each do |line, absentees| - record = nil - assert_nothing_raised do - record = @parser.parse_line(line) - end - - # Absent field is :absent, not "*" inside the record - absentees.each do |absentee| - assert_equal(:absent, record[absentee]) - end - - # Now regenerate the line - newline = nil - assert_nothing_raised do - newline = @parser.to_line(record) - end - - # And make sure they're equal - assert_equal(line, newline) - end - - # Now make sure it pukes if we don't provide the required fields - assert_raise(ArgumentError) do - @parser.to_line(:record_type => :record, :one => "yay") - end - end - - def test_record_rts - # Start with the default - assert_nothing_raised do - @parser.record_line :record, - :fields => %w{one two three four}, - :optional => %w{three four} - end - - - assert_equal( - "a b ", - - @parser.to_line(:record_type => :record, :one => "a", :two => "b") - ) - - # Now say yes to removing - @parser.clear_records - assert_nothing_raised do - @parser.record_line :record, - :fields => %w{one two three four}, - :optional => %w{three four}, - :rts => true - end - - - assert_equal( - "a b", - - @parser.to_line(:record_type => :record, :one => "a", :two => "b") - ) - - # Lastly, try a regex - @parser.clear_records - assert_nothing_raised do - @parser.record_line :record, - :fields => %w{one two three four}, - :optional => %w{three four}, - :absent => "*", - :rts => /[ *]+$/ - end - - - assert_equal( - "a b", - - @parser.to_line(:record_type => :record, :one => "a", :two => "b") - ) - end - - # Make sure the last field can contain the separator, as crontabs do, and - # that we roll them all up by default. - def test_field_rollups - @parser.record_line :yes, :fields => %w{name one two} - - result = nil - assert_nothing_raised do - result = @parser.send(:parse_line, "Name One Two Three") - end - - assert_equal( - "Two Three", result[:two], - - "Did not roll up last fields by default") - - @parser = FParser.new - assert_nothing_raised("Could not create record that rolls up fields") do - @parser.record_line :no, :fields => %w{name one two}, :rollup => false - end - - result = nil - assert_nothing_raised do - result = @parser.send(:parse_line, "Name One Two Three") - end - - assert_equal( - "Two", result[:two], - - "Rolled up last fields when rollup => false") - end - - def test_text_blocks - record = nil - assert_nothing_raised do - record = @parser.text_line :name, :match => %r{^#} do |line| - {:line => line.upcase} - end - end - - - assert( - record.respond_to?(:process), - - "Block was not used with text line") - - assert_equal("YAYNESS", record.process("yayness")[:line], - "Did not call process method") - end - - def test_hooks - record = nil - # First try it with a normal record - assert_nothing_raised("Could not set hooks") do - record = @parser.record_line :yay, :fields => %w{one two}, - :post_parse => proc { |hash| hash[:posted] = true }, - :pre_gen => proc { |hash| hash[:one] = hash[:one].upcase }, - :to_line => proc { |hash| "# Line\n" + join(hash) } - end - - assert(record.respond_to?(:post_parse), "did not create method for post-hook") - assert(record.respond_to?(:pre_gen), "did not create method for pre-hook") - - result = nil - assert_nothing_raised("Could not process line with hooks") do - result = @parser.parse_line("one two") - end - - assert(result[:posted], "Did not run post-hook") - old_result = result - - # Now make sure our pre-gen hook is called - assert_nothing_raised("Could not generate line with hooks") do - result = @parser.to_line(result) - end - assert_equal("# Line\nONE two", result, "did not call pre-gen hook") - assert_equal("one", old_result[:one], "passed original hash to pre hook") - end -end - -class TestUtilFileRecord < Test::Unit::TestCase - include PuppetTest - include PuppetTest::FileParsing - - Record = Puppet::Util::FileParsing::FileRecord - def test_new_filerecord - [ [:fake, {}], - [nil, ] - ].each do |args| - assert_raise(ArgumentError, "Did not fail on #{args.inspect}") do - Record.new(*args) - end - end - - # Make sure the fields get turned into symbols - record = nil - assert_nothing_raised do - record = Record.new(:record, :fields => %w{one two}) - end - assert_equal([:one, :two], record.fields, "Did not symbolize fields") - - # Make sure we fail on invalid fields - [:record_type, :target, :on_disk].each do |field| - assert_raise(ArgumentError, "Did not fail on invalid field #{field}") { - Record.new(:record, :fields => [field]) - } - end - end - - def test_defaults - record = Record.new(:text, :match => %r{^#}) - [:absent, :separator, :joiner, :optional].each do |field| - assert_nil(record.send(field), "#{field} was not nil") - end - - record = Record.new(:record, :fields => %w{fields}) - {:absent => "", :separator => /\s+/, :joiner => " ", :optional => []}.each do |field, default| - assert_equal(default, record.send(field), "#{field} was not default") - end - end - - def test_block - record = nil - assert_nothing_raised("Could not pass a block when creating record") do - record = Record.new(:record, :fields => %w{one}) do |line| - return line.upcase - end - end - - line = "This is a line" - - - assert( - record.respond_to?(:process), - - "Record did not define :process method") - - - assert_equal( - line.upcase, record.process(line), - - "Record did not process line correctly") - end - - # Make sure we can declare that we want the block to be instance-eval'ed instead of - # defining the 'process' method. - def test_instance_block - record = nil - assert_nothing_raised("Could not pass a block when creating record") do - record = Record.new(:record, :block_eval => :instance, :fields => %w{one}) do - def process(line) - line.upcase - end - - def to_line(details) - details.upcase - end - end - end - - assert(record.respond_to?(:process), "Block was not instance-eval'ed and process was not defined") - assert(record.respond_to?(:to_line), "Block was not instance-eval'ed and to_line was not defined") - - line = "some text" - assert_equal(line.upcase, record.process(line), "Instance-eval'ed record did not call :process correctly") - assert_equal(line.upcase, record.to_line(line), "Instance-eval'ed record did not call :to_line correctly") - end -end - - diff --git a/test/util/inifile.rb b/test/util/inifile.rb deleted file mode 100755 index e3ce20823..000000000 --- a/test/util/inifile.rb +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/util/inifile' -require 'puppettest' - -class TestFileType < Test::Unit::TestCase - include PuppetTest - - def setup - super - @file = Puppet::Util::IniConfig::File.new - end - - def teardown - @file = nil - super - end - - def test_simple - fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value=2") - assert_nothing_raised { - @file.read(fname) - } - s = get_section('main') - assert_entries(s, { 'key1' => 'value1', 'key2' => 'value=2' }) - @file['main']['key2'] = 'newvalue2' - @file['main']['key3'] = 'newvalue3' - text = s.format - - assert_equal( - "[main]\nkey1=value1\n# Comment\nkey2=newvalue2\nkey3=newvalue3\n", - - s.format) - end - - def test_multi - fmain = mkfile("[main]\nkey1=main.value1\n# Comment\nkey2=main.value2") - fsub = mkfile("[sub1]\nkey1=sub1 value1\n\n[sub2]\nkey1=sub2.value1") - main_mtime = File::stat(fmain).mtime - assert_nothing_raised { - @file.read(fmain) - @file.read(fsub) - } - main = get_section('main') - - assert_entries( - main, - - { 'key1' => 'main.value1', 'key2' => 'main.value2' }) - sub1 = get_section('sub1') - assert_entries(sub1, { 'key1' => 'sub1 value1' }) - sub2 = get_section('sub2') - assert_entries(sub2, { 'key1' => 'sub2.value1' }) - [main, sub1, sub2].each { |s| assert( !s.dirty? ) } - sub1['key1'] = 'sub1 newvalue1' - sub2['key2'] = 'sub2 newvalue2' - assert(! main.dirty?) - [sub1, sub2].each { |s| assert( s.dirty? ) } - @file.store - [main, sub1, sub2].each { |s| assert( !s.dirty? ) } - assert( File.exists?(fmain) ) - assert( File.exists?(fsub) ) - assert_equal(main_mtime, File::stat(fmain).mtime) - subtext = File.read(fsub) - - assert_equal( - "[sub1]\nkey1=sub1 newvalue1\n\n[sub2]\nkey1=sub2.value1\nkey2=sub2 newvalue2\n", - - subtext) - end - - def test_format_nil - fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value2\n# Comment2\n") - assert_nothing_raised { - @file.read(fname) - } - s = get_section('main') - s['key2'] = nil - s['key3'] = nil - text = s.format - - assert_equal( - "[main]\nkey1=value1\n# Comment\n# Comment2\n", - - s.format) - end - - def test_whitespace - # FIXME: Should we really accept keys preceded by whitespace ? - fname = mkfile("[main]\n key1=v1\nkey2 =v2\n") - assert_nothing_raised { - @file.read(fname) - } - s = get_section('main') - assert_equal('v1', s['key1']) - assert_equal('v2', s['key2']) - # FIXME: We are losing whitespace around keys - assert_equal("[main]\nkey1=v1\nkey2=v2\n", s.format) - end - - def test_continuation - cont = "[main]\nkey1=v1\nkey2=v2a\n v2b\nkey3=\n\tv3a\n v3b\n" - fname = mkfile(cont) - assert_nothing_raised { - @file.read(fname) - } - s = get_section('main') - assert_equal('v1', s['key1']) - assert_equal("v2a\n v2b", s['key2']) - assert_equal("\n\tv3a\n v3b", s['key3']) - assert_equal(cont, s.format) - end - - def assert_entries(section, hash) - hash.each do |k, v| - - assert_equal( - v, section[k], - - "Expected <#{v}> for #{section.name}[#{k}] but got <#{section[k]}>") - end - end - - def get_section(name) - result = @file[name] - assert_not_nil(result) - result - end - - def mkfile(content) - file = tempfile - File.open(file, "w") { |f| f.print(content) } - file - end -end diff --git a/test/util/instance_loader.rb b/test/util/instance_loader.rb deleted file mode 100755 index 61ca4e3c8..000000000 --- a/test/util/instance_loader.rb +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/util/instance_loader' -require 'puppettest' - -class TestInstanceloader < Test::Unit::TestCase - include PuppetTest - - def setup - super - @loader = Class.new do - extend Puppet::Util::InstanceLoader - - def self.newstuff(name, value) - instance_hash(:stuff)[name] = value - end - end - - assert_nothing_raised("Could not create instance loader") do - @loader.instance_load(:stuff, "puppet/stuff") - end - end - - # Make sure we correctly create our autoload instance. This covers the basics. - def test_autoload - # Make sure we can retrieve the loader - assert_instance_of(Puppet::Util::Autoload, @loader.instance_loader(:stuff), "Could not get instance loader") - - # Make sure we can get the instance hash - assert(@loader.instance_hash(:stuff), "Could not get instance hash") - - # Make sure it defines the instance retrieval method - assert(@loader.respond_to?(:stuff), "Did not define instance retrieval method") - end - - def test_loaded_instances - assert_equal([], @loader.loaded_instances(:stuff), "Incorrect loaded instances") - - @loader.newstuff(:testing, "a value") - - assert_equal([:testing], @loader.loaded_instances(:stuff), "Incorrect loaded instances") - - assert_equal("a value", @loader.loaded_instance(:stuff, :testing), "Got incorrect loaded instance") - end - - def test_instance_loading - end -end - diff --git a/test/util/log.rb b/test/util/log.rb deleted file mode 100755 index 908347a50..000000000 --- a/test/util/log.rb +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/util/log' -require 'puppettest' - -class TestLog < Test::Unit::TestCase - include PuppetTest - - def setup - super - @oldloglevel = Puppet::Util::Log.level - Puppet::Util::Log.close_all - end - - def teardown - super - Puppet::Util::Log.close_all - Puppet::Util::Log.level = @oldloglevel - end - - def getlevels - levels = nil - assert_nothing_raised { - levels = [] - Puppet::Util::Log.eachlevel { |level| levels << level } - } - # Don't test the top levels; too annoying - levels.reject { |level| level == :emerg or level == :crit } - end - - def mkmsgs(levels) - levels.collect { |level| - next if level == :alert - assert_nothing_raised { - - Puppet::Util::Log.new( - - :level => level, - :source => "Test", - - :message => "Unit test for #{level}" - ) - } - } - end - - def test_logfile - fact = nil - levels = nil - Puppet::Util::Log.level = :debug - levels = getlevels - logfile = tempfile - fact = nil - assert_nothing_raised { - Puppet::Util::Log.newdestination(logfile) - } - msgs = mkmsgs(levels) - assert(msgs.length == levels.length) - Puppet::Util::Log.close_all - count = 0 - - assert(FileTest.exists?(logfile), "Did not create logfile") - - assert_nothing_raised { - File.open(logfile) { |of| - count = of.readlines.length - } - } - assert(count == levels.length - 1) # skip alert - end - - def test_syslog - levels = nil - assert_nothing_raised { - levels = getlevels.reject { |level| - level == :emerg || level == :crit - } - } - assert_nothing_raised { - Puppet::Util::Log.newdestination("syslog") - } - # there's really no way to verify that we got syslog messages... - msgs = mkmsgs(levels) - assert(msgs.length == levels.length) - end - - def test_levelmethods - assert_nothing_raised { - Puppet::Util::Log.newdestination("/dev/null") - } - getlevels.each { |level| - assert_nothing_raised { - Puppet.send(level,"Testing for #{level}") - } - } - end - - def test_output - Puppet::Util::Log.level = :notice - assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log)) - assert(Puppet.debug("This is debugging").nil?) - Puppet::Util::Log.level = :debug - assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log)) - assert(Puppet.debug("This is debugging").is_a?(Puppet::Util::Log)) - end - - def test_creatingdirs - dir = tempfile - file = File.join(dir, "logfile") - Puppet::Util::Log.newdestination file - Puppet.info "testing logs" - assert(FileTest.directory?(dir)) - assert(FileTest.file?(file)) - end - - # Verify that we can pass strings that match printf args - def test_percentlogs - Puppet::Util::Log.newdestination :syslog - - assert_nothing_raised { - - Puppet::Util::Log.new( - - :level => :info, - - :message => "A message with %s in it" - ) - } - end - - # Verify that the error and source are always strings - def test_argsAreStrings - msg = nil - - file = Puppet::Type.type(:file).new( - - :path => tempfile, - - :check => %w{owner group} - ) - assert_nothing_raised { - msg = Puppet::Util::Log.new(:level => :info, :message => "This is a message") - } - assert_nothing_raised { - msg.source = file - } - - assert_instance_of(String, msg.to_s) - assert_instance_of(String, msg.source) - end - - def test_destination_matching - dest = nil - assert_nothing_raised { - dest = Puppet::Util::Log.newdesttype("Destine") do - def handle(msg) - puts msg - end - end - } - - [:destine, "Destine", "destine"].each do |name| - assert(dest.match?(name), "Did not match #{name.inspect}") - end - - assert_nothing_raised { - dest.match(:yayness) - } - assert(dest.match("Yayness"), "Did not match yayness") - Puppet::Util::Log.close(dest) - end - - def test_autoflush - file = tempfile - Puppet::Util::Log.close(:console) - Puppet::Util::Log.newdestination(file) - Puppet.warning "A test" - assert(File.read(file) !~ /A test/, "File defualted to autoflush") - Puppet::Util::Log.flush - assert(File.read(file) =~ /A test/, "File did not flush") - Puppet::Util::Log.close(file) - - # Now try one with autoflush enabled - Puppet[:autoflush] = true - file = tempfile - Puppet::Util::Log.newdestination(file) - Puppet.warning "A test" - assert(File.read(file) =~ /A test/, "File did not autoflush") - Puppet::Util::Log.close(file) - end - - def test_reopen - Puppet[:autoflush] = true - file = tempfile - Puppet::Util::Log.close(:console) - Puppet::Util::Log.newdestination(file) - Puppet.warning "A test" - assert(File.read(file) =~ /A test/, - "File did not flush") - # Rename the file - newfile = file + ".old" - File.rename(file, newfile) - - # Send another log - Puppet.warning "Another test" - assert(File.read(newfile) =~ /Another test/, - "File did not rename") - - # Now reopen the log - Puppet::Util::Log.reopen - Puppet.warning "Reopen test" - assert(File.read(file) =~ /Reopen test/, "File did not reopen") - Puppet::Util::Log.close(file) - end -end - diff --git a/test/util/metrics.rb b/test/util/metrics.rb deleted file mode 100755 index d1a052293..000000000 --- a/test/util/metrics.rb +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/util/metric' -require 'puppettest' -require 'puppet/type' - -class TestMetric < PuppetTest::TestCase - confine "Missing RRDtool library" => (Puppet.features.rrd? || Puppet.features.rrd_legacy?) - include PuppetTest - - def gendata - totalmax = 1000 - changemax = 1000 - eventmax = 10 - maxdiff = 10 - - types = [Puppet::Type.type(:file), Puppet::Type.type(:package), Puppet::Type.type(:package)] - data = [:total, :managed, :outofsync, :changed, :totalchanges] - events = [:file_changed, :package_installed, :service_started] - - # if this is the first set of data points... - typedata = Hash.new { |typehash,type| - typehash[type] = Hash.new(0) - } - eventdata = Hash.new(0) - typedata = {} - typedata[:total] = rand(totalmax) - typedata[:managed] = rand(typedata[:total]) - typedata[:outofsync] = rand(typedata[:managed]) - typedata[:changed] = rand(typedata[:outofsync]) - typedata[:totalchanges] = rand(changemax) - - events.each { |event| - eventdata[event] = rand(eventmax) - } - - {:typedata => typedata, :eventdata => eventdata} - end - - def rundata(report, time) - assert_nothing_raised { - gendata.each do |name, data| - report.add_metric(name, data) - end - report.metrics.each { |n, m| m.store(time) } - } - end - - def test_fakedata - report = Puppet::Transaction::Report.new - time = Time.now.to_i - start = time - 10.times { - rundata(report, time) - time += 300 - } - rundata(report, time) - - report.metrics.each do |n, m| m.graph end - - File.open(File.join(Puppet[:rrddir],"index.html"),"w") { |of| - of.puts "" - report.metrics.each { |name, metric| - of.puts "
" - } - } - end -end - diff --git a/test/util/package.rb b/test/util/package.rb deleted file mode 100755 index cd6a9d01d..000000000 --- a/test/util/package.rb +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppet/util/package' -require 'puppettest' - -class TestPuppetUtilPackage < Test::Unit::TestCase - include PuppetTest - include Puppet::Util::Package - - def test_versioncmp - ary = %w{ 1.1.6 2.3 1.1a 3.0 1.5 1 2.4 1.1-4 2.3.1 1.2 2.3.0 1.1-3 2.4b 2.4 2.40.2 2.3a.1 3.1 0002 1.1-5 1.1.a 1.06} - - newary = nil - assert_nothing_raised do - newary = ary.sort { |a, b| - versioncmp(a,b) - } - end - assert_equal(["0002", "1", "1.06", "1.1-3", "1.1-4", "1.1-5", "1.1.6", "1.1.a", "1.1a", "1.2", "1.5", "2.3", "2.3.0", "2.3.1", "2.3a.1", "2.4", "2.4", "2.4b", "2.40.2", "3.0", "3.1"], newary) - end -end - diff --git a/test/util/pidlock.rb b/test/util/pidlock.rb deleted file mode 100755 index 69aeb155f..000000000 --- a/test/util/pidlock.rb +++ /dev/null @@ -1,125 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet/util/pidlock' -require 'fileutils' - -# This is *fucked* *up* -Puppet.debug = false - -class TestPuppetUtilPidlock < Test::Unit::TestCase - include PuppetTest - - def setup - super - @workdir = tstdir - end - - def teardown - super - FileUtils.rm_rf(@workdir) - end - - def test_00_basic_create - l = nil - assert_nothing_raised { l = Puppet::Util::Pidlock.new(@workdir + '/nothingmuch') } - - assert_equal Puppet::Util::Pidlock, l.class - - assert_equal @workdir + '/nothingmuch', l.lockfile - end - - def test_10_uncontended_lock - l = Puppet::Util::Pidlock.new(@workdir + '/test_lock') - - assert !l.locked? - assert !l.mine? - assert l.lock - assert l.locked? - assert l.mine? - assert !l.anonymous? - # It's OK to call lock multiple times - assert l.lock - assert l.unlock - assert !l.locked? - assert !l.mine? - end - - def test_20_someone_elses_lock - childpid = nil - l = Puppet::Util::Pidlock.new(@workdir + '/someone_elses_lock') - - # First, we need a PID that's guaranteed to be (a) used, (b) someone - # else's, and (c) around for the life of this test. - childpid = fork { loop do; sleep 10; end } - - File.open(l.lockfile, 'w') { |fd| fd.write(childpid) } - - assert l.locked? - assert !l.mine? - assert !l.lock - assert l.locked? - assert !l.mine? - assert !l.unlock - assert l.locked? - assert !l.mine? - ensure - Process.kill("KILL", childpid) unless childpid.nil? - end - - def test_30_stale_lock - # This is a bit hard to guarantee, but we need a PID that is definitely - # unused, and will stay so for the the life of this test. Our best - # bet is to create a process, get it's PID, let it die, and *then* - # lock on it. - childpid = fork { exit } - - # Now we can't continue until we're sure that the PID is dead - Process.wait(childpid) - - l = Puppet::Util::Pidlock.new(@workdir + '/stale_lock') - - # locked? should clear the lockfile - File.open(l.lockfile, 'w') { |fd| fd.write(childpid) } - assert File.exists?(l.lockfile) - assert !l.locked? - assert !File.exists?(l.lockfile) - - # lock should replace the lockfile with our own - File.open(l.lockfile, 'w') { |fd| fd.write(childpid) } - assert File.exists?(l.lockfile) - assert l.lock - assert l.locked? - assert l.mine? - - # unlock should fail, but should clear the stale lockfile. - File.open(l.lockfile, 'w') { |fd| fd.write(childpid) } - assert File.exists?(l.lockfile) - assert !l.unlock - assert !File.exists?(l.lockfile) - end - - def test_40_not_locked_at_all - l = Puppet::Util::Pidlock.new(@workdir + '/not_locked') - - assert !l.locked? - # We can't unlock if we don't hold the lock - assert !l.unlock - end - - def test_50_anonymous_lock - l = Puppet::Util::Pidlock.new(@workdir + '/anonymous_lock') - - assert !l.locked? - assert l.lock(:anonymous => true) - assert l.locked? - assert l.anonymous? - assert !l.mine? - assert "", File.read(l.lockfile) - assert !l.unlock - assert l.locked? - assert l.anonymous? - assert l.unlock(:anonymous => true) - assert !File.exists?(l.lockfile) - end -end - diff --git a/test/util/settings.rb b/test/util/settings.rb deleted file mode 100755 index 0da0b26a6..000000000 --- a/test/util/settings.rb +++ /dev/null @@ -1,743 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'mocha' -require 'puppettest' -require 'puppet/util/settings' -require 'puppettest/parsertesting' - -class TestSettings < Test::Unit::TestCase - include PuppetTest - include PuppetTest::ParserTesting - Setting = Puppet::Util::Settings::StringSetting - BooleanSetting = Puppet::Util::Settings::BooleanSetting - - def setup - super - @config = mkconfig - end - - def set_configs(config = nil) - config ||= @config - - config.define_settings( - "main", - :one => { :type => :string, :default => "a", :desc => "one" }, - :two => { :type => :string, :default => "a", :desc => "two" }, - :yay => { :type => :string, :default => "/default/path", :desc => "boo" }, - :mkusers => { :type => :boolean, :default => true, :desc => "uh, yeah" }, - - :name => { :type => :string, :default => "testing", :desc => "a" } - ) - - - config.define_settings( - "section1", - :attr => { :type => :string, :default => "a", :desc => "one" }, - :attrdir => { :type => :directory, :default => "/another/dir", :desc => "two" }, - - :attr3 => { :type => :string, :default => "$attrdir/maybe", :desc => "boo" } - ) - end - - def check_for_users - count = Puppet::Type.type(:user).inject(0) { |c,o| - c + 1 - } - assert(count > 0, "Found no users") - end - - def test_to_config - set_configs - - newc = mkconfig - set_configs(newc) - - # Reset all of the values, so we know they're changing. - newc.each do |name, obj| - next if name == :name - newc[name] = true - end - - newfile = tempfile - File.open(newfile, "w") { |f| - @config.to_config.split("\n").each do |line| - # Uncomment the settings, so they actually take. - if line =~ / = / - f.puts line.sub(/^\s*#/, '') - else - f.puts line - end - end - } - - newc.define_settings :section, :config => { :type => :file, :default => newfile, :desc => "eh" } - - assert_nothing_raised("Could not parse generated configuration") { - newc.parse - } - - @config.each do |name, object| - assert_equal(@config[name], newc[name], "Parameter #{name} is not the same") - end - end - - def mkconfig - c = Puppet::Util::Settings.new - c.define_settings :main, :noop => { :type => :boolean, :default => false, :desc => "foo" } - c - end - - def test_addbools - assert_nothing_raised { - @config.define_settings(:testing, :booltest => { :type => :boolean, :default => true, :desc => "testing" }) - } - - assert(@config[:booltest]) - @config = mkconfig - - assert_nothing_raised { - @config.define_settings(:testing, :booltest => { :type => :boolean, :default => "true", :desc => "testing" }) - } - - assert(@config[:booltest]) - - assert_nothing_raised { - @config[:booltest] = false - } - - assert(! @config[:booltest], "Booltest is not false") - - assert_nothing_raised { - @config[:booltest] = "false" - } - - assert(! @config[:booltest], "Booltest is not false") - - assert_raise(ArgumentError) { - @config[:booltest] = "yayness" - } - - assert_raise(ArgumentError) { - @config[:booltest] = "/some/file" - } - end - - def test_strings - val = "this is a string" - assert_nothing_raised { - @config.define_settings(:testing, :strtest => { :type => :string, :default => val, :desc => "testing" }) - } - - assert_equal(val, @config[:strtest]) - - # Verify that variables are interpolated - assert_nothing_raised { - @config.define_settings(:testing, :another => { :type => :string, :default => "another $strtest", :desc => "testing" }) - } - - assert_equal("another #{val}", @config[:another]) - end - - def test_files - c = mkconfig - - parent = "/puppet" - assert_nothing_raised { - @config.define_settings(:testing, :parentdir => { :type => :directory, :default => parent, :desc => "booh" }) - } - - assert_nothing_raised { - @config.define_settings(:testing, :child => { :type => :file, :default => "$parent/child", :desc => "rah" }) - } - - assert_equal(parent, @config[:parentdir]) - assert_equal("/puppet/child", File.join(@config[:parentdir], "child")) - end - - def test_getset - initial = "an initial value" - assert_raise(ArgumentError) { - @config[:yayness] = initial - } - - default = "this is a default" - assert_nothing_raised { - @config.define_settings(:testing, :yayness => { :type => :string, :default => default, :desc => "rah" }) - } - - assert_equal(default, @config[:yayness]) - - assert_nothing_raised { - @config[:yayness] = initial - } - - assert_equal(initial, @config[:yayness]) - - assert_nothing_raised { - @config.clear - } - - assert_equal(default, @config[:yayness], "'clear' did not remove old values") - - assert_nothing_raised { - @config[:yayness] = "not default" - } - assert_equal("not default", @config[:yayness]) - end - - def test_parse_file - text = %{ - one = this is a test - two = another test - owner = root - group = root - yay = /a/path - - [main] - four = five - six = seven - -[section1] - attr = value - owner = puppet - group = puppet - attrdir = /some/dir - attr3 = $attrdir/other - } - - file = tempfile - File.open(file, "w") { |f| f.puts text } - - result = nil - assert_nothing_raised { - result = @config.send(:parse_file, file) - } - - main = result[:main] - assert(main, "Did not get section for main") - { - :one => "this is a test", - :two => "another test", - :owner => "root", - :group => "root", - :yay => "/a/path", - :four => "five", - :six => "seven" - }.each do |param, value| - assert_equal(value, main[param], "Param #{param} was not set correctly in main") - end - - section1 = result[:section1] - assert(section1, "Did not get section1") - - { - :attr => "value", - :owner => "puppet", - :group => "puppet", - :attrdir => "/some/dir", - :attr3 => "$attrdir/other" - }.each do |param, value| - assert_equal(value, section1[param], "Param #{param} was not set correctly in section1") - end - end - - def test_arghandling - c = mkconfig - - assert_nothing_raised { - - @config.define_settings( - "testing", - :onboolean => { :type => :boolean, :default => true, :desc => "An on bool" }, - :offboolean => { :type => :boolean, :default => false, :desc => "An off bool" }, - :string => { :type => :string, :default => "a string", :desc => "A string arg" }, - - :file => { :type => :file, :default => "/path/to/file", :desc => "A file arg" } - ) - } - - data = { - :onboolean => [true, false], - :offboolean => [true, false], - :string => ["one string", "another string"], - :file => %w{/a/file /another/file} - } - data.each { |param, values| - values.each { |val| - opt = nil - arg = nil - if @config.boolean?(param) - if val - opt = "--#{param}" - else - opt = "--no-#{param}" - end - else - opt = "--#{param}" - arg = val - end - - assert_nothing_raised("Could not handle arg #{opt} with value #{val}") { - - @config.handlearg(opt, arg) - } - } - } - end - - def test_addargs - - @config.define_settings( - "testing", - :onboolean => { :type => :boolean, :default => true, :desc => "An on bool" }, - :offboolean => { :type => :boolean, :default => false, :desc => "An off bool" }, - :string => { :type => :string, :default => "a string", :desc => "A string arg" }, - - :file => { :type => :file, :default => "/path/to/file", :desc => "A file arg" } - ) - - should = [] - @config.each { |name, element| - element.expects(:getopt_args).returns([name]) - should << name - } - result = [] - assert_nothing_raised("Add args failed") do - @config.addargs(result) - end - assert_equal(should, result, "Did not call addargs correctly.") - - end - - def test_addargs_functional - @config = Puppet::Util::Settings.new - - - @config.define_settings( - "testing", - :onboolean => { :type => :boolean, :default => true, :desc => "An on bool" }, - - :string => { :type => :string, :default => "a string", :desc => "A string arg" } - ) - result = [] - should = [] - assert_nothing_raised("Add args failed") do - @config.addargs(result) - end - @config.each do |name, element| - if name == :onboolean - should << ["--onboolean", GetoptLong::NO_ARGUMENT] - should << ["--no-onboolean", GetoptLong::NO_ARGUMENT] - elsif name == :string - should << ["--string", GetoptLong::REQUIRED_ARGUMENT] - end - end - assert_equal(should, result, "Add args functional test failed") - end - - def test_groupsetting - cfile = tempfile - - group = "yayness" - - File.open(cfile, "w") do |f| - f.puts "[main] - group = #{group} - " - end - - config = mkconfig - config.define_settings(:application, - :group => { :type => :string, :default => "puppet", :desc => "a group" }, - :config => { :type => :file, :default => cfile, :desc => "eh" }) - - assert_nothing_raised { - config.parse - } - - assert_equal(group, config[:group], "Group did not take") - end - - # provide a method to modify and create files w/out specifying the info - # already stored in a config - def test_writingfiles - File.umask(0022) - - path = tempfile - mode = 0644 - - config = mkconfig - - args = { :type => :file, :default => path, :mode => mode, :desc => "yay" } - - user = nonrootuser - group = nonrootgroup - - if Puppet.features.root? - args[:owner] = user.name - args[:group] = group.name - end - - config.define_settings(:testing, :myfile => args) - - assert_nothing_raised { - config.write(:myfile) do |file| - file.puts "yay" - end - } - - assert_equal(mode, filemode(path), "Modes are not equal") - - # OS X is broken in how it chgrps files - if Puppet.features.root? - assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal") - - case Facter["operatingsystem"].value - when /BSD/, "Darwin" # nothing - else - assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal") - end - end - end - - def test_mkdir - File.umask(0022) - - path = tempfile - mode = 0755 - - config = mkconfig - - args = { :type => :directory, :default => path, :mode => mode, :desc => "a file" } - - user = nonrootuser - group = nonrootgroup - - if Puppet.features.root? - args[:owner] = user.name - args[:group] = group.name - end - - config.define_settings(:testing, :mydir => args) - - assert_nothing_raised { - config.mkdir(:mydir) - } - - assert_equal(mode, filemode(path), "Modes are not equal") - - - # OS X and *BSD is broken in how it chgrps files - if Puppet.features.root? - assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal") - - case Facter["operatingsystem"].value - when /BSD/, "Darwin" # nothing - else - assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal") - end - end - end - - # Make sure that tags are ignored when configuring - def test_configs_ignore_tags - config = mkconfig - file = tempfile - - - config.define_settings( - :mysection, - - :mydir => { :type => :directory, :default => file, :desc => "a file" } - ) - - Puppet[:tags] = "yayness" - - assert_nothing_raised { - config.use(:mysection) - } - - assert(FileTest.directory?(file), "Directory did not get created") - - - assert_equal( - "yayness", Puppet[:tags], - - "Tags got changed during config") - end - - def test_configs_replace_in_url - config = mkconfig - - config.define_settings(:mysection, :host => { :type => :string, :default => "yayness", :desc => "yay" }) - config.define_settings(:mysection, :url => { :type => :string, :default => "http://$host/rahness", :desc => "yay" }) - - val = nil - assert_nothing_raised { - val = config[:url] - } - - - assert_equal( - "http://yayness/rahness", val, - - "Settings got messed up") - end - - def test_parse_removes_quotes - config = mkconfig - config.define_settings(:mysection, :singleq => { :type => :string, :default => "single", :desc => "yay" }) - config.define_settings(:mysection, :doubleq => { :type => :string, :default => "double", :desc => "yay" }) - config.define_settings(:mysection, :none => { :type => :string, :default => "noquote", :desc => "yay" }) - config.define_settings(:mysection, :middle => { :type => :string, :default => "midquote", :desc => "yay" }) - - file = tempfile - # Set one parameter in the file - File.open(file, "w") { |f| - f.puts %{[main]\n - singleq = 'one' - doubleq = "one" - none = one - middle = mid"quote -} - } - - config.define_settings(:mysection, :config => { :type => :file, :default => file, :desc => "eh" }) - - assert_nothing_raised { - config.parse - } - - %w{singleq doubleq none}.each do |p| - assert_equal("one", config[p], "#{p} did not match") - end - assert_equal('mid"quote', config["middle"], "middle did not match") - end - - # Test that config parameters correctly call passed-in blocks when the value - # is set. - def test_paramblocks - config = mkconfig - - testing = nil - assert_nothing_raised do - config.define_settings :test, :blocktest => {:default => "yay", :desc => "boo", :hook => proc { |value| testing = value }} - end - elem = config.setting(:blocktest) - - assert_nothing_raised do - assert_equal("yay", elem.value) - end - - assert_nothing_raised do - config[:blocktest] = "yaytest" - end - - assert_nothing_raised do - assert_equal("yaytest", elem.value) - end - assert_equal("yaytest", testing) - - assert_nothing_raised do - config[:blocktest] = "another" - end - - assert_nothing_raised do - assert_equal("another", elem.value) - end - assert_equal("another", testing) - - # Now verify it works from setdefault - assert_nothing_raised do - config.define_settings :test, - :blocktest2 => { - :default => "yay", - :desc => "yay", - :hook => proc { |v| testing = v } - } - end - - assert_equal("yay", config[:blocktest2]) - - assert_nothing_raised do - config[:blocktest2] = "footest" - end - assert_equal("footest", config[:blocktest2]) - assert_equal("footest", testing) - end - - def test_no_modify_root - config = mkconfig - - config.define_settings(:yay, - :mydir => { - :type => :file, - :default => tempfile, - :mode => 0644, - :owner => "root", - :group => "service", - :desc => "yay" - }, - :mkusers => { :type => :boolean, :default => false, :desc => "yay" } - ) - - assert_nothing_raised do - config.use(:yay) - end - - # Now enable it so they'll be added - config[:mkusers] = true - - comp = config.to_catalog - - comp.vertices.find_all { |r| r.class.name == :user }.each do |u| - assert(u.name != "root", "Tried to manage root user") - end - comp.vertices.find_all { |r| r.class.name == :group }.each do |u| - assert(u.name != "root", "Tried to manage root group") - assert(u.name != "wheel", "Tried to manage wheel group") - end - -# assert(yay, "Did not find yay component") -# yay.each do |c| -# puts @config.ref -# end -# assert(! yay.find { |o| o.class.name == :user and o.name == "root" }, -# "Found root user") -# assert(! yay.find { |o| o.class.name == :group and o.name == "root" }, -# "Found root group") - end - - # #415 - def test_remove_trailing_spaces - config = mkconfig - file = tempfile - File.open(file, "w") { |f| f.puts "rah = something " } - - config.define_settings(:yay, :config => { :type => :file, :default => file, :desc => "eh" }, :rah => { :type => :string, :default => "testing", :desc => "a desc" }) - - assert_nothing_raised { config.parse } - assert_equal("something", config[:rah], "did not remove trailing whitespace in parsing") - end - - # #484 - def test_parsing_unknown_variables - logstore - config = mkconfig - file = tempfile - File.open(file, "w") { |f| - f.puts %{[main]\n - one = one - two = yay - } - } - - config.define_settings(:mysection, :config => { :type => :file, :default => file, :desc => "eh" }, :one => { :type => :string, :default => "yay", :desc => "yay" }) - - assert_nothing_raised("Unknown parameter threw an exception") do - config.parse - end - end - - def test_multiple_interpolations - - @config.define_settings( - :section, - :one => { :type => :string, :default => "oneval", :desc => "yay" }, - :two => { :type => :string, :default => "twoval", :desc => "yay" }, - - :three => { :type => :string, :default => "$one/$two", :desc => "yay" } - ) - - - assert_equal( - "oneval/twoval", @config[:three], - - "Did not interpolate multiple variables") - end - - # Make sure we can replace ${style} var names - def test_curly_replacements - - @config.define_settings( - :section, - :one => { :type => :string, :default => "oneval", :desc => "yay" }, - :two => { :type => :string, :default => "twoval", :desc => "yay" }, - - :three => { :type => :string, :default => "$one/${two}/${one}/$two", :desc => "yay" } - ) - - - assert_equal( - "oneval/twoval/oneval/twoval", @config[:three], - - "Did not interpolate curlied variables") - end - - # Test to make sure that we can set and get a short name - def test_setting_short_name - setting= nil - assert_nothing_raised("Could not create setting") do - setting= Setting.new :short => "n", :desc => "anything", :settings => Puppet::Util::Settings.new - end - assert_equal("n", setting.short, "Short value is not retained") - - assert_raise(ArgumentError,"Allowed multicharactered short names.") do - setting= Setting.new :short => "no", :desc => "anything", :settings => Puppet::Util::Settings.new - end - end - - # Test to make sure that no two celements have the same short name - def test_celement_short_name_not_duplicated - config = mkconfig - assert_nothing_raised("Could not create celement with short name.") do - - config.define_settings( - :main, - - :one => { :default => "blah", :desc => "anything", :short => "o" }) - end - assert_nothing_raised("Could not create second celement with short name.") do - - config.define_settings( - :main, - - :two => { :default => "blah", :desc => "anything", :short => "i" }) - end - assert_raise(ArgumentError, "Could create second celement with duplicate short name.") do - - config.define_settings( - :main, - - :three => { :default => "blah", :desc => "anything", :short => "i" }) - end - # make sure that when the above raises an expection that the config is not included - assert(!config.include?(:three), "Invalid configuration item was retained") - end - - # Tell getopt which arguments are valid - def test_get_getopt_args - element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new - assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args") - - element.short = "n" - assert_equal([["--foo", "-n", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args") - - element = BooleanSetting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new - - assert_equal( - [["--foo", GetoptLong::NO_ARGUMENT], ["--no-foo", GetoptLong::NO_ARGUMENT]], - - element.getopt_args, "Did not produce appropriate getopt args") - - element.short = "n" - - assert_equal( - [["--foo", "-n", GetoptLong::NO_ARGUMENT],["--no-foo", GetoptLong::NO_ARGUMENT]], - - element.getopt_args, "Did not produce appropriate getopt args") - end -end - diff --git a/test/util/storage.rb b/test/util/storage.rb deleted file mode 100755 index 26bf70952..000000000 --- a/test/util/storage.rb +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppet' -require 'puppettest' - -class TestStorage < Test::Unit::TestCase - include PuppetTest - - def mkfile - path = tempfile - File.open(path, "w") { |f| f.puts :yayness } - - - f = Puppet::Type.type(:file).new( - - :name => path, - - :check => %w{checksum type} - ) - - f - end - - def test_storeandretrieve - path = tempfile - - f = mkfile - - # Load first, since that's what we do in the code base; this creates - # all of the necessary directories. - assert_nothing_raised { - Puppet::Util::Storage.load - } - - hash = {:a => :b, :c => :d} - - state = nil - assert_nothing_raised { - state = Puppet::Util::Storage.cache(f) - } - - assert(!state.include?("name")) - - assert_nothing_raised { - state["name"] = hash - } - - assert_nothing_raised { - Puppet::Util::Storage.store - } - assert_nothing_raised { - Puppet::Util::Storage.clear - } - assert_nothing_raised { - Puppet::Util::Storage.load - } - - # Reset it - state = nil - assert_nothing_raised { - state = Puppet::Util::Storage.cache(f) - } - - assert_equal(state["name"], hash) - end - - def test_emptyrestore - Puppet::Util::Storage.load - Puppet::Util::Storage.store - Puppet::Util::Storage.clear - Puppet::Util::Storage.load - - f = mkfile - state = Puppet::Util::Storage.cache(f) - assert_same Hash, state.class - assert_equal 0, state.size - end -end - diff --git a/test/util/subclass_loader.rb b/test/util/subclass_loader.rb deleted file mode 100755 index c3453157e..000000000 --- a/test/util/subclass_loader.rb +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'puppet/util/subclass_loader' - -class TestPuppetUtilSubclassLoader < Test::Unit::TestCase - include PuppetTest - - class LoadTest - extend Puppet::Util::SubclassLoader - handle_subclasses :faker, "puppet/fakeloaders" - end - - def mk_subclass(name, path, parent) - # Make a fake client - unless defined?(@basedir) - @basedir ||= tempfile - $LOAD_PATH << @basedir - cleanup { $LOAD_PATH.delete(@basedir) if $LOAD_PATH.include?(@basedir) } - end - - libdir = File.join([@basedir, path.split(File::SEPARATOR)].flatten) - FileUtils.mkdir_p(libdir) - - file = File.join(libdir, "#{name}.rb") - File.open(file, "w") do |f| - f.puts %{class #{parent}::#{name.to_s.capitalize} < #{parent}; end} - end - end - - def test_subclass_loading - # Make a fake client - mk_subclass("fake", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest") - - - fake = nil - assert_nothing_raised do - fake = LoadTest.faker(:fake) - end - assert_nothing_raised do - assert_equal(fake, LoadTest.fake, "Did not get subclass back from main method") - end - assert(fake, "did not load subclass") - - # Now make sure the subclass behaves correctly - assert_equal(:Fake, fake.name, "name was not calculated correctly") - end - - def test_multiple_subclasses - sub1 = Class.new(LoadTest) - Object.const_set("Sub1", sub1) - sub2 = Class.new(sub1) - Object.const_set("Sub2", sub2) - assert_equal(sub2, LoadTest.sub2, "did not get subclass of subclass") - end - - # I started out using a class variable to mark the loader, - # but it's shared among all classes that include this module, - # so it didn't work. This is testing whether I get the behaviour - # that I want. - def test_multiple_classes_using_module - other = Class.new do - extend Puppet::Util::SubclassLoader - handle_subclasses :other, "puppet/other" - end - Object.const_set("OtherLoader", other) - - mk_subclass("multipletest", "puppet/other", "OtherLoader") - mk_subclass("multipletest", "puppet/fakeloaders", "TestPuppetUtilSubclassLoader::LoadTest") - #system("find #{@basedir}") - #puts File.read(File.join(@basedir, "puppet/fakeloaders/multipletest.rb")) - #puts File.read(File.join(@basedir, "puppet/other/multipletest.rb")) - - othersub = mainsub = nil - assert_nothing_raised("Could not look up other sub") do - othersub = OtherLoader.other(:multipletest) - end - assert_nothing_raised("Could not look up main sub") do - mainsub = LoadTest.faker(:multipletest) - end - assert(othersub, "did not get other sub") - assert(mainsub, "did not get main sub") - assert(othersub.ancestors.include?(OtherLoader), "othersub is not a subclass of otherloader") - assert(mainsub.ancestors.include?(LoadTest), "mainsub is not a subclass of loadtest") - end -end - diff --git a/test/util/utiltest.rb b/test/util/utiltest.rb deleted file mode 100755 index 8a7ab83c7..000000000 --- a/test/util/utiltest.rb +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.dirname(__FILE__) + '/../lib/puppettest') - -require 'puppettest' -require 'mocha' - -class TestPuppetUtil < Test::Unit::TestCase - include PuppetTest - - def test_withumask - oldmask = File.umask - - path = tempfile - - # FIXME this fails on FreeBSD with a mode of 01777 - Puppet::Util.withumask(000) do - Dir.mkdir(path, 0777) - end - - assert(File.stat(path).mode & 007777 == 0777, "File has the incorrect mode") - assert_equal(oldmask, File.umask, "Umask was not reset") - end - - def test_benchmark - path = tempfile - str = "yayness" - File.open(path, "w") do |f| f.print "yayness" end - - # First test it with the normal args - assert_nothing_raised do - val = nil - result = Puppet::Util.benchmark(:notice, "Read file") do - val = File.read(path) - end - - assert_equal(str, val) - - assert_instance_of(Float, result) - - end - - # Now test it with a passed object - assert_nothing_raised do - val = nil - Puppet::Util.benchmark(Puppet, :notice, "Read file") do - val = File.read(path) - end - - assert_equal(str, val) - end - end - - def test_proxy - klass = Class.new do - attr_accessor :hash - class << self - attr_accessor :ohash - end - end - klass.send(:include, Puppet::Util) - - klass.ohash = {} - - inst = klass.new - inst.hash = {} - assert_nothing_raised do - Puppet::Util.proxy klass, :hash, "[]", "[]=", :clear, :delete - end - - assert_nothing_raised do - Puppet::Util.classproxy klass, :ohash, "[]", "[]=", :clear, :delete - end - - assert_nothing_raised do - inst[:yay] = "boo" - inst["cool"] = :yayness - end - - [:yay, "cool"].each do |var| - assert_equal(inst.hash[var], inst[var], "Var #{var} did not take") - end - - assert_nothing_raised do - klass[:Yay] = "boo" - klass["Cool"] = :yayness - end - - [:Yay, "Cool"].each do |var| - assert_equal(inst.hash[var], inst[var], "Var #{var} did not take") - end - end - - def test_symbolize - ret = nil - assert_nothing_raised { - ret = Puppet::Util.symbolize("yayness") - } - - assert_equal(:yayness, ret) - - assert_nothing_raised { - ret = Puppet::Util.symbolize(:yayness) - } - - assert_equal(:yayness, ret) - - assert_nothing_raised { - ret = Puppet::Util.symbolize(43) - } - - assert_equal(43, ret) - - assert_nothing_raised { - ret = Puppet::Util.symbolize(nil) - } - - assert_equal(nil, ret) - end - - def test_execute - command = tempfile - File.open(command, "w") { |f| - f.puts %{#!/bin/sh\n/bin/echo "$1">&1; echo "$2">&2} - } - File.chmod(0755, command) - output = nil - assert_nothing_raised do - output = Puppet::Util::Execution.execute([command, "yaytest", "funtest"]) - end - assert_equal("yaytest\nfuntest\n", output) - - # Now try it with a single quote - assert_nothing_raised do - output = Puppet::Util::Execution.execute([command, "yay'test", "funtest"]) - end - assert_equal("yay'test\nfuntest\n", output) - - # Now make sure we can squelch output (#565) - assert_nothing_raised do - output = Puppet::Util::Execution.execute([command, "yay'test", "funtest"], :squelch => true) - end - assert_equal(nil, output) - - # Now test that we correctly fail if the command returns non-zero - assert_raise(Puppet::ExecutionFailure) do - out = Puppet::Util::Execution.execute(["touch", "/no/such/file/could/exist"]) - end - - # And that we can tell it not to fail - assert_nothing_raised do - out = Puppet::Util::Execution.execute(["touch", "/no/such/file/could/exist"], :failonfail => false) - end - - if Process.uid == 0 - # Make sure we correctly set our uid and gid - user = nonrootuser - group = nonrootgroup - file = tempfile - assert_nothing_raised do - Puppet::Util::Execution.execute(["touch", file], :uid => user.name, :gid => group.name) - end - assert(FileTest.exists?(file), "file was not created") - assert_equal(user.uid, File.stat(file).uid, "uid was not set correctly") - - # We can't really check the gid, because it just behaves too - # inconsistently everywhere. - # assert_equal(group.gid, File.stat(file).gid, - # "gid was not set correctly") - end - - # (#565) Test the case of patricide. - patricidecommand = tempfile - File.open(patricidecommand, "w") { |f| - f.puts %{#!/bin/bash\n/bin/bash -c 'kill -TERM \$PPID' &;\n while [ 1 ]; do echo -n ''; done;\n} - } - File.chmod(0755, patricidecommand) - assert_nothing_raised do - output = Puppet::Util::Execution.execute([patricidecommand], :squelch => true, :failonfail => false) - end - assert_equal(nil, output) - # See what happens if we try and read the pipe to the command... - assert_raise(Puppet::ExecutionFailure) do - output = Puppet::Util::Execution.execute([patricidecommand]) - end - assert_nothing_raised do - output = Puppet::Util::Execution.execute([patricidecommand], :failonfail => false) - end - end - -end -