diff --git a/lib/puppet/feature/rails.rb b/lib/puppet/feature/rails.rb index e0e14ebeb..2763b0676 100644 --- a/lib/puppet/feature/rails.rb +++ b/lib/puppet/feature/rails.rb @@ -1,35 +1,35 @@ # Created by Luke Kanies on 2006-11-07. # Copyright (c) 2006. All rights reserved. require 'puppet/util/feature' Puppet.features.rubygems? Puppet.features.add(:rails) do begin require 'active_record' require 'active_record/version' rescue LoadError => detail if FileTest.exists?("/usr/share/rails") count = 0 Dir.entries("/usr/share/rails").each do |dir| libdir = File.join("/usr/share/rails", dir, "lib") if FileTest.exists?(libdir) and ! $LOAD_PATH.include?(libdir) count += 1 $LOAD_PATH << libdir end end retry if count > 0 end end if ! (defined?(::ActiveRecord) and defined?(::ActiveRecord::VERSION) and defined?(::ActiveRecord::VERSION::MAJOR) and defined?(::ActiveRecord::VERSION::MINOR)) false - elsif ! (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR >= 1) + elsif ! (([::ActiveRecord::VERSION::MAJOR, ::ActiveRecord::VERSION::MINOR].join('.').to_f) >= 2.1) Puppet.info "ActiveRecord 2.1 or later required for StoreConfigs" false else true end end diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb index 414b1bc18..6bf5d4abd 100644 --- a/lib/puppet/rails.rb +++ b/lib/puppet/rails.rb @@ -1,136 +1,136 @@ # Load the appropriate libraries, or set a class indicating they aren't available require 'facter' require 'puppet' module Puppet::Rails TIME_DEBUG = true def self.connect # This global init does not work for testing, because we remove # the state dir on every test. return if ActiveRecord::Base.connected? Puppet.settings.use(:main, :rails, :master) ActiveRecord::Base.logger = Logger.new(Puppet[:railslog]) begin loglevel = Logger.const_get(Puppet[:rails_loglevel].upcase) ActiveRecord::Base.logger.level = loglevel rescue => detail Puppet.warning "'#{Puppet[:rails_loglevel]}' is not a valid Rails log level; using debug" ActiveRecord::Base.logger.level = Logger::DEBUG end - if (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1) + if (([::ActiveRecord::VERSION::MAJOR, ::ActiveRecord::VERSION::MINOR].join('.').to_f) >= 2.1) ActiveRecord::Base.allow_concurrency = true end ActiveRecord::Base.verify_active_connections! begin args = database_arguments Puppet.info "Connecting to #{args[:adapter]} database: #{args[:database]}" ActiveRecord::Base.establish_connection(args) rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "Could not connect to database: #{detail}" end end # The arguments for initializing the database connection. def self.database_arguments adapter = Puppet[:dbadapter] args = {:adapter => adapter, :log_level => Puppet[:rails_loglevel]} case adapter when "sqlite3" args[:database] = Puppet[:dblocation] when "mysql", "postgresql" args[:host] = Puppet[:dbserver] unless Puppet[:dbserver].to_s.empty? args[:port] = Puppet[:dbport] unless Puppet[:dbport].to_s.empty? args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty? args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty? args[:database] = Puppet[:dbname] args[:reconnect]= true socket = Puppet[:dbsocket] args[:socket] = socket unless socket.to_s.empty? connections = Puppet[:dbconnections].to_i args[:pool] = connections if connections > 0 when "oracle_enhanced": args[:database] = Puppet[:dbname] unless Puppet[:dbname].to_s.empty? args[:username] = Puppet[:dbuser] unless Puppet[:dbuser].to_s.empty? args[:password] = Puppet[:dbpassword] unless Puppet[:dbpassword].to_s.empty? connections = Puppet[:dbconnections].to_i args[:pool] = connections if connections > 0 else raise ArgumentError, "Invalid db adapter #{adapter}" end args end # Set up our database connection. It'd be nice to have a "use" system # that could make callbacks. def self.init raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" unless Puppet.features.rails? connect unless ActiveRecord::Base.connection.tables.include?("resources") require 'puppet/rails/database/schema' Puppet::Rails::Schema.init end migrate if Puppet[:dbmigrate] end # Migrate to the latest db schema. def self.migrate dbdir = nil $LOAD_PATH.each { |d| tmp = File.join(d, "puppet/rails/database") if FileTest.directory?(tmp) dbdir = tmp break end } raise Puppet::Error, "Could not find Puppet::Rails database dir" unless dbdir raise Puppet::Error, "Database has problems, can't migrate." unless ActiveRecord::Base.connection.tables.include?("resources") Puppet.notice "Migrating" begin ActiveRecord::Migrator.migrate(dbdir) rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "Could not migrate database: #{detail}" end end # Tear down the database. Mostly only used during testing. def self.teardown raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" unless Puppet.features.rails? Puppet.settings.use(:master, :rails) begin ActiveRecord::Base.establish_connection(database_arguments) rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "Could not connect to database: #{detail}" end ActiveRecord::Base.connection.tables.each do |t| ActiveRecord::Base.connection.drop_table t end end end require 'puppet/rails/host' if Puppet.features.rails? diff --git a/spec/unit/rails_spec.rb b/spec/unit/rails_spec.rb index eaa968099..13c5a8a25 100755 --- a/spec/unit/rails_spec.rb +++ b/spec/unit/rails_spec.rb @@ -1,258 +1,258 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../spec_helper' require 'puppet/rails' describe Puppet::Rails, "when initializing any connection" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? before do Puppet.settings.stubs(:use) @logger = mock 'logger' @logger.stub_everything Logger.stubs(:new).returns(@logger) ActiveRecord::Base.stubs(:logger).returns(@logger) ActiveRecord::Base.stubs(:connected?).returns(false) end it "should use settings" do Puppet.settings.expects(:use).with(:main, :rails, :master) Puppet::Rails.connect end it "should set up a logger with the appropriate Rails log file" do logger = mock 'logger' Logger.expects(:new).with(Puppet[:railslog]).returns(logger) ActiveRecord::Base.expects(:logger=).with(logger) Puppet::Rails.connect end it "should set the log level to whatever the value is in the settings" do Puppet.settings.stubs(:use) Puppet.settings.stubs(:value).with(:rails_loglevel).returns("debug") Puppet.settings.stubs(:value).with(:railslog).returns("/my/file") logger = mock 'logger' Logger.stubs(:new).returns(logger) ActiveRecord::Base.stubs(:logger).returns(logger) logger.expects(:level=).with(Logger::DEBUG) ActiveRecord::Base.stubs(:allow_concurrency=) ActiveRecord::Base.stubs(:verify_active_connections!) ActiveRecord::Base.stubs(:establish_connection) Puppet::Rails.stubs(:database_arguments).returns({}) Puppet::Rails.connect end describe "on ActiveRecord 2.1.x" do - confine("ActiveRecord 2.1.x") { ::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1 } + confine("ActiveRecord 2.1.x") { ([::ActiveRecord::VERSION::MAJOR, ::ActiveRecord::VERSION::MINOR].join('.').to_f) >= 2.1 } it "should set ActiveRecord::Base.allow_concurrency" do ActiveRecord::Base.expects(:allow_concurrency=).with(true) Puppet::Rails.connect end end it "should call ActiveRecord::Base.verify_active_connections!" do ActiveRecord::Base.expects(:verify_active_connections!) Puppet::Rails.connect end it "should call ActiveRecord::Base.establish_connection with database_arguments" do Puppet::Rails.expects(:database_arguments).returns({}) ActiveRecord::Base.expects(:establish_connection) Puppet::Rails.connect end end describe Puppet::Rails, "when initializing a sqlite3 connection" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? it "should provide the adapter, log_level, and database arguments" do Puppet.settings.expects(:value).with(:dbadapter).returns("sqlite3") Puppet.settings.expects(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.expects(:value).with(:dblocation).returns("testlocation") Puppet::Rails.database_arguments.should == { :adapter => "sqlite3", :log_level => "testlevel", :database => "testlocation" } end end describe Puppet::Rails, "when initializing a mysql connection" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? it "should provide the adapter, log_level, and host, port, username, password, database, and reconnect arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbserver).returns("testserver") Puppet.settings.stubs(:value).with(:dbport).returns("") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbsocket).returns("") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "mysql", :log_level => "testlevel", :host => "testserver", :username => "testuser", :password => "testpassword", :database => "testname", :reconnect => true, :pool => 1 } end it "should provide the adapter, log_level, and host, port, username, password, database, socket, connections, and reconnect arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbserver).returns("testserver") Puppet.settings.stubs(:value).with(:dbport).returns("9999") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "mysql", :log_level => "testlevel", :host => "testserver", :port => "9999", :username => "testuser", :password => "testpassword", :database => "testname", :socket => "testsocket", :reconnect => true, :pool => 1 } end it "should provide the adapter, log_level, and host, port, username, password, database, socket, and connections arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("mysql") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbserver).returns("testserver") Puppet.settings.stubs(:value).with(:dbport).returns("9999") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "mysql", :log_level => "testlevel", :host => "testserver", :port => "9999", :username => "testuser", :password => "testpassword", :database => "testname", :socket => "testsocket", :reconnect => true, :pool => 1 } end end describe Puppet::Rails, "when initializing a postgresql connection" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? it "should provide the adapter, log_level, and host, port, username, password, connections, and database arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("postgresql") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbserver).returns("testserver") Puppet.settings.stubs(:value).with(:dbport).returns("9999") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbsocket).returns("") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "postgresql", :log_level => "testlevel", :host => "testserver", :port => "9999", :username => "testuser", :password => "testpassword", :database => "testname", :reconnect => true, :pool => 1 } end it "should provide the adapter, log_level, and host, port, username, password, database, connections, and socket arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("postgresql") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbserver).returns("testserver") Puppet.settings.stubs(:value).with(:dbport).returns("9999") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbsocket).returns("testsocket") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "postgresql", :log_level => "testlevel", :host => "testserver", :port => "9999", :username => "testuser", :password => "testpassword", :database => "testname", :socket => "testsocket", :pool => 1, :reconnect => true } end end describe Puppet::Rails, "when initializing an Oracle connection" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? it "should provide the adapter, log_level, and username, password, dbconnections, and database arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "oracle_enhanced", :log_level => "testlevel", :username => "testuser", :password => "testpassword", :database => "testname", :pool => 1 } end it "should provide the adapter, log_level, and host, username, password, database, pool, and socket arguments" do Puppet.settings.stubs(:value).with(:dbadapter).returns("oracle_enhanced") Puppet.settings.stubs(:value).with(:rails_loglevel).returns("testlevel") Puppet.settings.stubs(:value).with(:dbuser).returns("testuser") Puppet.settings.stubs(:value).with(:dbpassword).returns("testpassword") Puppet.settings.stubs(:value).with(:dbname).returns("testname") Puppet.settings.stubs(:value).with(:dbconnections).returns(1) Puppet::Rails.database_arguments.should == { :adapter => "oracle_enhanced", :log_level => "testlevel", :username => "testuser", :password => "testpassword", :database => "testname", :pool => 1 } end end