diff --git a/Manifest.txt b/Manifest.txt index ff992d8..03f1e90 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -11,15 +11,12 @@ doco/getting_started.txt doco/migration.txt doco/perforce.txt doco/variables.txt -lib/rake_remote_task.rb lib/vlad.rb lib/vlad/apache.rb lib/vlad/core.rb lib/vlad/maintenance.rb lib/vlad/passenger.rb lib/vlad/subversion.rb -lib/vlad_test_case.rb -test/test_rake_remote_task.rb test/test_vlad.rb test/test_vlad_subversion.rb vladdemo.sh diff --git a/Rakefile b/Rakefile index 993359d..8583bc1 100644 --- a/Rakefile +++ b/Rakefile @@ -5,6 +5,8 @@ require 'hoe' Hoe.plugin :seattlerb +Hoe.add_include_dirs "../../rake-remote_task/dev/lib" + Hoe.spec 'vlad' do self.rubyforge_name = 'hitsquad' @@ -13,6 +15,7 @@ Hoe.spec 'vlad' do developer 'Wilson Bilkovich', 'wilson@supremetyrant.com' extra_deps << ['rake', '~> 0.8.0'] + extra_deps << ['rake-remote_task', '~> 2.0'] extra_deps << ['open4', '~> 0.9.0'] # TODO: remove 1.9 @@ -21,6 +24,8 @@ end desc "quick little hack to see what the state of the nation looks like" task :debug do + $: << 'lib' + require 'vlad' Vlad.load :config => "lib/vlad/subversion.rb" set :repository, "repository path" set :deploy_to, "deploy path" @@ -29,17 +34,4 @@ task :debug do Rake::Task['vlad:debug'].invoke end -task :mana_from_heaven do - # vlad = vlad + rake + open4 - # rake sans-contrib = 2035.98356718206 - vlad = `flog -s lib`.to_f + 2350.30744806517 + 502.363818023761 - cap = 11480.3919695285 - ratio = cap / vlad - target = cap / Math::PI - - puts "%14.8f = %s" % [vlad, "vlad"] - puts "%14.8f = %s" % [ratio, "ratio"] - puts "%14.8f = %s" % [target - vlad, "needed delta"] -end - # vim: syntax=ruby diff --git a/lib/rake_remote_task.rb b/lib/rake_remote_task.rb deleted file mode 100644 index cf85f38..0000000 --- a/lib/rake_remote_task.rb +++ /dev/null @@ -1,589 +0,0 @@ -require 'rubygems' -require 'open4' -require 'rake' -require 'vlad' - -$TESTING ||= false -$TRACE = Rake.application.options.trace -$-w = true if $TRACE # asshat, don't mess with my warn. - -def export receiver, *methods - methods.each do |method| - eval "def #{method} *args, █ #{receiver}.#{method}(*args, &block);end" - end -end - -export "Thread.current[:task]", :get, :put, :rsync, :run, :sudo, :target_host -export "Rake::RemoteTask", :host, :remote_task, :role, :set - -## -# Rake::RemoteTask is a subclass of Rake::Task that adds -# remote_actions that execute in parallel on multiple hosts via ssh. - -class Rake::RemoteTask < Rake::Task - - @@current_roles = [] - - include Open4 - - ## - # Options for execution of this task. - - attr_accessor :options - - ## - # The host this task is running on during execution. - - attr_accessor :target_host - - ## - # An Array of Actions this host will perform during execution. Use - # enhance to add new actions to a task. - - attr_reader :remote_actions - - def self.current_roles - @@current_roles - end - - ## - # Create a new task named +task_name+ attached to Rake::Application +app+. - - def initialize(task_name, app) - super - - @remote_actions = [] - @happy = false # used for deprecation warnings on get/put/rsync - end - - ## - # Add a local action to this task. This calls Rake::Task#enhance. - - alias_method :original_enhance, :enhance - - ## - # Add remote action +block+ to this task with dependencies +deps+. See - # Rake::Task#enhance. - - def enhance(deps=nil, &block) - original_enhance(deps) # can't use super because block passed regardless. - @remote_actions << Action.new(self, block) if block_given? - self - end - - ## - # Execute this action. Local actions will be performed first, then remote - # actions will be performed in parallel on each host configured for this - # RemoteTask. - - def execute(args = nil) - raise(Vlad::ConfigurationError, - "No target hosts specified on task #{self.name} for roles #{options[:roles].inspect}") if - ! defined_target_hosts? - - super args - - @remote_actions.each { |act| act.execute(target_hosts, self, args) } - end - - ## - # Pull +files+ from the remote +host+ using rsync to +local_dir+. - # TODO: what if role has multiple hosts & the files overlap? subdirs? - - def get local_dir, *files - @happy = true - host = target_host - rsync files.map { |f| "#{host}:#{f}" }, local_dir - @happy = false - end - - ## - # Copy a (usually generated) file to +remote_path+. Contents of block - # are copied to +remote_path+ and you may specify an optional - # base_name for the tempfile (aids in debugging). - - def put remote_path, base_name = File.basename(remote_path) - require 'tempfile' - Tempfile.open base_name do |fp| - fp.puts yield - fp.flush - @happy = true - rsync fp.path, "#{target_host}:#{remote_path}" - @happy = false - end - end - - ## - # Execute rsync with +args+. Tacks on pre-specified +rsync_cmd+ and - # +rsync_flags+. - # - # Favor #get and #put for most tasks. Old-style direct use where the - # target_host was implicit is now deprecated. - - def rsync *args - unless @happy || args[-1] =~ /:/ then - warn "rsync deprecation: pass target_host:remote_path explicitly" - args[-1] = "#{target_host}:#{args[-1]}" - end - - cmd = [rsync_cmd, rsync_flags, args].flatten.compact - cmdstr = cmd.join ' ' - - warn cmdstr if $TRACE - - success = system(*cmd) - - raise Vlad::CommandFailedError, "execution failed: #{cmdstr}" unless success - end - - ## - # Use ssh to execute +command+ on target_host. If +command+ uses sudo, the - # sudo password will be prompted for then saved for subsequent sudo commands. - - def run command - cmd = [ssh_cmd, ssh_flags, target_host, command].flatten - result = [] - - trace = [ssh_cmd, ssh_flags, target_host, "'#{command}'"].flatten.join(' ') - warn trace if $TRACE - - pid, inn, out, err = popen4(*cmd) - - inn.sync = true - streams = [out, err] - out_stream = { - out => $stdout, - err => $stderr, - } - - # Handle process termination ourselves - status = nil - Thread.start do - status = Process.waitpid2(pid).last - end - - until streams.empty? do - # don't busy loop - selected, = select streams, nil, nil, 0.1 - - next if selected.nil? or selected.empty? - - selected.each do |stream| - if stream.eof? then - streams.delete stream if status # we've quit, so no more writing - next - end - - data = stream.readpartial(1024) - out_stream[stream].write data - - if stream == err and data =~ sudo_prompt then - inn.puts sudo_password - data << "\n" - $stderr.write "\n" - end - - result << data - end - end - - unless status.success? then - raise(Vlad::CommandFailedError, - "execution failed with status #{status.exitstatus}: #{cmd.join ' '}") - end - - result.join - ensure - inn.close rescue nil - out.close rescue nil - err.close rescue nil - end - - ## - # Returns an Array with every host configured. - - def self.all_hosts - hosts_for(roles.keys) - end - - ## - # The default environment values. Used for resetting (mostly for - # tests). - - def self.default_env - @@default_env - end - - def self.per_thread - @@per_thread - end - - ## - # The vlad environment. - - def self.env - @@env - end - - ## - # Fetches environment variable +name+ from the environment using - # default +default+. - - def self.fetch name, default = nil - name = name.to_s if Symbol === name - if @@env.has_key? name then - protect_env(name) do - v = @@env[name] - v = @@env[name] = v.call if Proc === v unless per_thread[name] - v = v.call if Proc === v - v - end - elsif default || default == false - v = @@env[name] = default - else - raise Vlad::FetchError - end - end - - ## - # Add host +host_name+ that belongs to +roles+. Extra arguments may - # be specified for the host as a hash as the last argument. - # - # host is the inversion of role: - # - # host 'db1.example.com', :db, :master_db - # - # Is equivalent to: - # - # role :db, 'db1.example.com' - # role :master_db, 'db1.example.com' - - def self.host host_name, *roles - opts = Hash === roles.last ? roles.pop : {} - - roles.each do |role_name| - role role_name, host_name, opts.dup - end - end - - ## - # Returns an Array of all hosts in +roles+. - - def self.hosts_for *roles - roles.flatten.map { |r| - self.roles[r].keys - }.flatten.uniq.sort - end - - def self.mandatory name, desc # :nodoc: - self.set(name) do - raise(Vlad::ConfigurationError, - "Please specify the #{desc} via the #{name.inspect} variable") - end - end - - ## - # Ensures exclusive access to +name+. - - def self.protect_env name # :nodoc: - @@env_locks[name].synchronize do - yield - end - end - - ## - # Adds a remote task named +name+ with options +options+ that will - # execute +block+. - - def self.remote_task name, *args, &block - options = (Hash === args.last) ? args.pop : {} - t = Rake::RemoteTask.define_task(name, *args, &block) - options[:roles] = Array options[:roles] - options[:roles] |= @@current_roles - t.options = options - t - end - - ## - # Ensures +name+ does not conflict with an existing method. - - def self.reserved_name? name # :nodoc: - !@@env.has_key?(name.to_s) && self.respond_to?(name) - end - - ## - # Resets vlad, restoring all roles, tasks and environment variables - # to the defaults. - - def self.reset - @@def_role_hash = {} # official default role value - @@env = {} - @@tasks = {} - @@roles = Hash.new { |h,k| h[k] = @@def_role_hash } - @@env_locks = Hash.new { |h,k| h[k] = Mutex.new } - - @@default_env.each do |k,v| - case v - when Symbol, Fixnum, nil, true, false, 42 then # ummmm... yeah. bite me. - @@env[k] = v - else - @@env[k] = v.dup - end - end - end - - ## - # Adds role +role_name+ with +host+ and +args+ for that host. - # TODO: merge: - # Declare a role and assign a remote host to it. Equivalent to the - # host method; provided for capistrano compatibility. - - def self.role role_name, host = nil, args = {} - if block_given? then - raise ArgumentError, 'host not allowed with block' unless host.nil? - - begin - current_roles << role_name - yield - ensure - current_roles.delete role_name - end - else - raise ArgumentError, 'host required' if host.nil? - - [*host].each do |hst| - raise ArgumentError, "invalid host: #{hst}" if hst.nil? or hst.empty? - end - @@roles[role_name] = {} if @@def_role_hash.eql? @@roles[role_name] - @@roles[role_name][host] = args - end - end - - ## - # The configured roles. - - def self.roles - host domain, :app, :web, :db if @@roles.empty? - - @@roles - end - - ## - # Set environment variable +name+ to +value+ or +default_block+. - # - # If +default_block+ is defined, the block will be executed the - # first time the variable is fetched, and the value will be used for - # every subsequent fetch. - - def self.set name, value = nil, &default_block - raise ArgumentError, "cannot provide both a value and a block" if - value and default_block unless - value == :per_thread - raise ArgumentError, "cannot set reserved name: '#{name}'" if - Rake::RemoteTask.reserved_name?(name) unless $TESTING - - name = name.to_s - - Rake::RemoteTask.per_thread[name] = true if - default_block && value == :per_thread - - Rake::RemoteTask.default_env[name] = Rake::RemoteTask.env[name] = - default_block || value - - Object.send :define_method, name do - Rake::RemoteTask.fetch name - end - end - - ## - # Sets all the default values. Should only be called once. Use reset - # if you need to restore values. - - def self.set_defaults - @@default_env ||= {} - @@per_thread ||= {} - self.reset - - mandatory :repository, "repository path" - mandatory :deploy_to, "deploy path" - mandatory :domain, "server domain" - - simple_set(:deploy_timestamped, true, - :deploy_via, :export, - :keep_releases, 5, - :migrate_args, "", - :migrate_target, :latest, - :rails_env, "production", - :rake_cmd, "rake", - :revision, "head", - :rsync_cmd, "rsync", - :rsync_flags, ['-azP', '--delete'], - :ssh_cmd, "ssh", - :ssh_flags, [], - :sudo_cmd, "sudo", - :sudo_flags, ['-p Password:'], - :sudo_prompt, /^Password:/, - :umask, '02') - - set(:current_release) { File.join(releases_path, releases[-1]) } - set(:latest_release) { deploy_timestamped ?release_path: current_release } - set(:previous_release) { File.join(releases_path, releases[-2]) } - set(:release_name) { Time.now.utc.strftime("%Y%m%d%H%M%S") } - set(:release_path) { File.join(releases_path, release_name) } - set(:releases) { task.run("ls -x #{releases_path}").split.sort } - - set_path :current_path, "current" - set_path :releases_path, "releases" - set_path :scm_path, "scm" - set_path :shared_path, "shared" - - set(:sudo_password) do - state = `stty -g` - - raise Vlad::Error, "stty(1) not found" unless $?.success? - - begin - system "stty -echo" - $stdout.print "sudo password: " - $stdout.flush - sudo_password = $stdin.gets - $stdout.puts - ensure - system "stty #{state}" - end - sudo_password - end - end - - def self.set_path(name, subdir) # :nodoc: - set(name) { File.join(deploy_to, subdir) } - end - - def self.simple_set(*args) # :nodoc: - args = Hash[*args] - args.each do |k, v| - set k, v - end - end - - ## - # The Rake::RemoteTask executing in this Thread. - - def self.task - Thread.current[:task] - end - - ## - # The configured Rake::RemoteTasks. - - def self.tasks - @@tasks - end - - ## - # Execute +command+ under sudo using run. - - def sudo command - run [sudo_cmd, sudo_flags, command].flatten.compact.join(" ") - end - - ## - # The hosts this task will execute on. The hosts are determined from - # the role this task belongs to. - # - # The target hosts may be overridden by providing a comma-separated - # list of commands to the HOSTS environment variable: - # - # rake my_task HOSTS=app1.example.com,app2.example.com - - def target_hosts - if hosts = ENV["HOSTS"] then - hosts.strip.gsub(/\s+/, '').split(",") - else - roles = Array options[:roles] - - if roles.empty? then - Rake::RemoteTask.all_hosts - else - Rake::RemoteTask.hosts_for roles - end - end - end - - ## - # Similar to target_hosts, but returns true if user defined any hosts, even - # an empty list. - - def defined_target_hosts? - return true if ENV["HOSTS"] - roles = Array options[:roles] - return true if roles.empty? - # borrowed from hosts_for: - roles.flatten.each { |r| - return true unless @@def_role_hash.eql? Rake::RemoteTask.roles[r] - } - return false - end - - ## - # Action is used to run a task's remote_actions in parallel on each - # of its hosts. Actions are created automatically in - # Rake::RemoteTask#enhance. - - class Action - - ## - # The task this action is attached to. - - attr_reader :task - - ## - # The block this action will execute. - - attr_reader :block - - ## - # An Array of threads, one for each host this action executes on. - - attr_reader :workers - - ## - # Creates a new Action that will run +block+ for +task+. - - def initialize task, block - @task = task - @block = block - @workers = ThreadGroup.new - end - - def == other # :nodoc: - return false unless Action === other - block == other.block && task == other.task - end - - ## - # Execute this action on +hosts+ in parallel. Returns when block - # has completed for each host. - - def execute hosts, task, args - hosts.each do |host| - t = task.clone - t.target_host = host - thread = Thread.new(t) do |task| - Thread.current[:task] = task - case block.arity - when 1 - block.call task - else - block.call task, args - end - Thread.current[:task] = nil - end - @workers.add thread - end - @workers.list.each { |thr| thr.join } - end - end -end - -Rake::RemoteTask.set_defaults diff --git a/lib/vlad.rb b/lib/vlad.rb index 60e7aba..d6ea237 100644 --- a/lib/vlad.rb +++ b/lib/vlad.rb @@ -1,11 +1,12 @@ require 'rubygems' require 'thread' -require 'rake_remote_task' +require 'rake/remote_task' $TESTING ||= false ## -# Vlad the Deployer - Pragmatic application deployment automation, without mercy. +# Vlad the Deployer - Pragmatic application deployment automation, +# without mercy. # # Please read doco/getting_started.txt or http://rubyhitsquad.com/ # @@ -22,22 +23,6 @@ module Vlad # This is the version of Vlad you are running. VERSION = '2.0.0' - ## - # Base error class for all Vlad errors. - class Error < RuntimeError; end - - ## - # Raised when you have incorrectly configured Vlad. - class ConfigurationError < Error; end - - ## - # Raised when a remote command fails. - class CommandFailedError < Error; end - - ## - # Raised when an environment variable hasn't been set. - class FetchError < Error; end - ## # Loads tasks file +tasks_file+ and various recipe styles as a hash # of category/style pairs. Recipes default to: diff --git a/lib/vlad_test_case.rb b/lib/vlad_test_case.rb deleted file mode 100644 index ac46cd7..0000000 --- a/lib/vlad_test_case.rb +++ /dev/null @@ -1,72 +0,0 @@ -require 'minitest/autorun' -require 'stringio' -require 'vlad' - -class StringIO - def readpartial(size) read end # suck! -end - -module Process - def self.expected status - @@expected ||= [] - @@expected << status - end - - class << self - alias :waitpid2_old :waitpid2 - - def waitpid2(pid) - [ @@expected.shift ] - end - end -end - -class Rake::RemoteTask - attr_accessor :commands, :action, :input, :output, :error - - Status = Struct.new :exitstatus - - class Status - def success?() exitstatus == 0 end - end - - def system *command - @commands << command - self.action ? self.action[command.join(' ')] : true - end - - def popen4 *command - @commands << command - - @input = StringIO.new - out = StringIO.new @output.shift.to_s - err = StringIO.new @error.shift.to_s - - raise if block_given? - - status = self.action ? self.action[command.join(' ')] : 0 - Process.expected Status.new(status) - - return 42, @input, out, err - end - - def select reads, writes, errs, timeout - [reads, writes, errs] - end - -end - -class VladTestCase < MiniTest::Unit::TestCase - def setup - @vlad = Rake::RemoteTask - @vlad.reset - Rake.application.clear - @task_count = Rake.application.tasks.size - @vlad.set :domain, "example.com" - end - - def util_set_hosts - @vlad.host "app.example.com", :app - @vlad.host "db.example.com", :db - end -end diff --git a/test/test_rake_remote_task.rb b/test/test_rake_remote_task.rb deleted file mode 100644 index eb55e25..0000000 --- a/test/test_rake_remote_task.rb +++ /dev/null @@ -1,261 +0,0 @@ -require 'vlad_test_case' -require 'vlad' - -class TestRakeRemoteTask < VladTestCase - # TODO: move to minitest - def assert_silent - out, err = capture_io do - yield - end - - assert_empty err - assert_empty out - end - - def test_enhance - util_set_hosts - body = Proc.new { 5 } - task = @vlad.remote_task(:some_task => :foo, &body) - action = Rake::RemoteTask::Action.new(task, body) - assert_equal [action], task.remote_actions - assert_equal task, action.task - assert_equal ["foo"], task.prerequisites - end - - def test_enhance_with_no_task_body - util_set_hosts - util_setup_task - assert_equal [], @task.remote_actions - assert_equal [], @task.prerequisites - end - - def test_execute - util_set_hosts - set :some_variable, 1 - set :can_set_nil, nil - set :lies_are, false - x = 5 - task = @vlad.remote_task(:some_task) { x += some_variable } - task.execute nil - assert_equal 1, task.some_variable - assert_equal 7, x - assert task.can_set_nil.nil? - assert_equal false, task.lies_are - end - - def test_set_false - set :can_set_nil, nil - set :lies_are, false - - assert_equal nil, task.can_set_nil - - assert_equal false, task.lies_are - assert_equal false, Rake::RemoteTask.fetch(:lies_are) - end - - - def test_fetch_false - assert_equal false, Rake::RemoteTask.fetch(:unknown, false) - end - - def test_execute_exposes_target_host - host "app.example.com", :app - task = remote_task(:target_task) { set(:test_target_host, target_host) } - task.execute nil - assert_equal "app.example.com", Rake::RemoteTask.fetch(:test_target_host) - end - - def test_execute_with_no_hosts - @vlad.host "app.example.com", :app - t = @vlad.remote_task(:flunk, :roles => :db) { flunk "should not have run" } - e = assert_raises(Vlad::ConfigurationError) { t.execute nil } - assert_equal "No target hosts specified on task flunk for roles [:db]", - e.message - end - - def test_execute_with_no_roles - t = @vlad.remote_task(:flunk, :roles => :junk) { flunk "should not have run" } - e = assert_raises(Vlad::ConfigurationError) { t.execute nil } - assert_equal "No target hosts specified on task flunk for roles [:junk]", - e.message - end - - def test_execute_with_roles - util_set_hosts - set :some_variable, 1 - x = 5 - task = @vlad.remote_task(:some_task, :roles => :db) { x += some_variable } - task.execute nil - assert_equal 1, task.some_variable - assert_equal 6, x - end - - def test_rsync - util_setup_task - @task.target_host = "app.example.com" - - assert_silent do - @task.rsync 'localfile', 'host:remotefile' - end - - commands = @task.commands - - assert_equal 1, commands.size, 'not enough commands' - assert_equal(%w[rsync -azP --delete localfile host:remotefile], - commands.first) - end - - def test_rsync_fail - util_setup_task - @task.target_host = "app.example.com" - @task.action = lambda { false } - - e = assert_raises Vlad::CommandFailedError do - assert_silent do - @task.rsync 'local', 'host:remote' - end - end - exp = "execution failed: rsync -azP --delete local host:remote" - assert_equal exp, e.message - end - - def test_rsync_deprecation - util_setup_task - @task.target_host = "app.example.com" - - out, err = capture_io do - @task.rsync 'localfile', 'remotefile' - end - - commands = @task.commands - - assert_equal 1, commands.size, 'not enough commands' - assert_equal(%w[rsync -azP --delete localfile app.example.com:remotefile], - commands.first) - - assert_equal("rsync deprecation: pass target_host:remote_path explicitly\n", - err) - assert_empty out - # flunk "not yet" - end - - def test_get - util_setup_task - @task.target_host = "app.example.com" - - assert_silent do - @task.get 'tmp', "remote1", "remote2" - end - - commands = @task.commands - - expected = %w[rsync -azP --delete app.example.com:remote1 app.example.com:remote2 tmp] - - assert_equal 1, commands.size - assert_equal expected, commands.first - end - - def test_put - util_setup_task - @task.target_host = "app.example.com" - - assert_silent do - @task.put 'dest' do - "whatever" - end - end - - commands = @task.commands - - expected = %w[rsync -azP --delete HAPPY app.example.com:dest] - commands.first[3] = 'HAPPY' - - assert_equal 1, commands.size - assert_equal expected, commands.first - end - - def test_run - util_setup_task - @task.output << "file1\nfile2\n" - @task.target_host = "app.example.com" - result = nil - - out, err = capture_io do - result = @task.run("ls") - end - - commands = @task.commands - - assert_equal 1, commands.size, 'not enough commands' - assert_equal ["ssh", "app.example.com", "ls"], - commands.first, 'app' - assert_equal "file1\nfile2\n", result - - assert_equal "file1\nfile2\n", out - assert_equal '', err - end - - def test_run_failing_command - util_set_hosts - util_setup_task - @task.input = StringIO.new "file1\nfile2\n" - @task.target_host = 'app.example.com' - @task.action = lambda { 1 } - - e = assert_raises(Vlad::CommandFailedError) { @task.run("ls") } - assert_equal "execution failed with status 1: ssh app.example.com ls", e.message - - assert_equal 1, @task.commands.size - end - - def test_run_sudo - util_setup_task - @task.output << "file1\nfile2\n" - @task.error << 'Password:' - @task.target_host = "app.example.com" - def @task.sudo_password() "my password" end # gets defined by set - result = nil - - out, err = capture_io do - result = @task.run("sudo ls") - end - - commands = @task.commands - - assert_equal 1, commands.size, 'not enough commands' - assert_equal ['ssh', 'app.example.com', 'sudo ls'], - commands.first - - assert_equal "my password\n", @task.input.string - - # WARN: Technically incorrect, the password line should be - # first... this is an artifact of changes to the IO code in run - # and the fact that we have a very simplistic (non-blocking) - # testing model. - assert_equal "file1\nfile2\nPassword:\n", result - - assert_equal "file1\nfile2\n", out - assert_equal "Password:\n", err - end - - def test_sudo - util_setup_task - @task.target_host = "app.example.com" - @task.sudo "ls" - - commands = @task.commands - - assert_equal 1, commands.size, 'wrong number of commands' - assert_equal ["ssh", "app.example.com", "sudo -p Password: ls"], - commands.first, 'app' - end - - def util_setup_task(options = {}) - @task = @vlad.remote_task :test_task, options - @task.commands = [] - @task.output = [] - @task.error = [] - @task.action = nil - @task - end -end diff --git a/test/test_vlad.rb b/test/test_vlad.rb index babe52a..db04088 100644 --- a/test/test_vlad.rb +++ b/test/test_vlad.rb @@ -1,112 +1,111 @@ -require 'vlad_test_case' -require 'vlad' +require 'rake/test_case' $TESTING = true -class TestVlad < VladTestCase +class TestVlad < Rake::TestCase def test_all_hosts util_set_hosts - assert_equal %w[app.example.com db.example.com], @vlad.all_hosts + assert_equal %w[app.example.com db.example.com], @rake.all_hosts end def test_fetch set :foo, 5 - assert_equal 5, @vlad.fetch(:foo) + assert_equal 5, @rake.fetch(:foo) end def test_fetch_with_default - assert_equal 5, @vlad.fetch(:not_here, 5) + assert_equal 5, @rake.fetch(:not_here, 5) end def test_host - @vlad.host "test.example.com", :app, :db + @rake.host "test.example.com", :app, :db expected = {"test.example.com" => {}} - assert_equal expected, @vlad.roles[:app] - assert_equal expected, @vlad.roles[:db] + assert_equal expected, @rake.roles[:app] + assert_equal expected, @rake.roles[:db] end def test_host_invalid - assert_raises(ArgumentError) { @vlad.host nil, :web } + assert_raises(ArgumentError) { @rake.host nil, :web } end def test_host_multiple_hosts - @vlad.host "test.example.com", :app, :db - @vlad.host "yarr.example.com", :app, :db, :no_release => true + @rake.host "test.example.com", :app, :db + @rake.host "yarr.example.com", :app, :db, :no_release => true expected = { "test.example.com" => {}, "yarr.example.com" => {:no_release => true} } - assert_equal expected, @vlad.roles[:app] - assert_equal expected, @vlad.roles[:db] - refute_equal(@vlad.roles[:db]["test.example.com"].object_id, - @vlad.roles[:app]["test.example.com"].object_id) + assert_equal expected, @rake.roles[:app] + assert_equal expected, @rake.roles[:db] + refute_equal(@rake.roles[:db]["test.example.com"].object_id, + @rake.roles[:app]["test.example.com"].object_id) end def test_hosts_for_array_of_roles util_set_hosts - assert_equal %w[app.example.com db.example.com], @vlad.hosts_for([:app, :db]) + assert_equal %w[app.example.com db.example.com], @rake.hosts_for([:app, :db]) end def test_hosts_for_one_role util_set_hosts - @vlad.host "app2.example.com", :app - assert_equal %w[app.example.com app2.example.com], @vlad.hosts_for(:app) + @rake.host "app2.example.com", :app + assert_equal %w[app.example.com app2.example.com], @rake.hosts_for(:app) end def test_hosts_for_multiple_roles util_set_hosts - assert_equal %w[app.example.com db.example.com], @vlad.hosts_for(:app, :db) + assert_equal %w[app.example.com db.example.com], @rake.hosts_for(:app, :db) end def test_hosts_for_unique util_set_hosts - @vlad.host "app.example.com", :web - assert_equal %w[app.example.com db.example.com], @vlad.hosts_for(:app, :db, :web) + @rake.host "app.example.com", :web + assert_equal %w[app.example.com db.example.com], @rake.hosts_for(:app, :db, :web) end def test_initialize - @vlad.set_defaults # ensure these three are virginal - assert_raises(Vlad::ConfigurationError) { @vlad.repository } - assert_raises(Vlad::ConfigurationError) { @vlad.deploy_to } - assert_raises(Vlad::ConfigurationError) { @vlad.domain } + @rake.set_defaults # ensure these three are virginal + assert_raises(Rake::ConfigurationError) { @rake.repository } + assert_raises(Rake::ConfigurationError) { @rake.deploy_to } + assert_raises(Rake::ConfigurationError) { @rake.domain } end def test_role - @vlad.role :app, "test.example.com" + @rake.role :app, "test.example.com" expected = {"test.example.com" => {}} - assert_equal expected, @vlad.roles[:app] + assert_equal expected, @rake.roles[:app] end def test_role_multiple_hosts - @vlad.role :app, "test.example.com" - @vlad.role :app, "yarr.example.com", :no_release => true + @rake.role :app, "test.example.com" + @rake.role :app, "yarr.example.com", :no_release => true expected = { "test.example.com" => {}, "yarr.example.com" => {:no_release => true} } - assert_equal expected, @vlad.roles[:app] + assert_equal expected, @rake.roles[:app] end def test_role_multiple_roles - @vlad.role :app, "test.example.com", :primary => true - @vlad.role :db, "yarr.example.com", :no_release => true + @rake.role :app, "test.example.com", :primary => true + @rake.role :db, "yarr.example.com", :no_release => true expected_db = { "yarr.example.com" => {:no_release => true} } - assert_equal expected_db, @vlad.roles[:db] + assert_equal expected_db, @rake.roles[:db] expected_app = { "test.example.com" => {:primary => true} } - assert_equal expected_app, @vlad.roles[:app] + assert_equal expected_app, @rake.roles[:app] end def test_remote_task - t = @vlad.remote_task(:test_task) { 5 } + t = @rake.remote_task(:test_task) { 5 } assert_equal @task_count + 1, Rake.application.tasks.size assert_equal({ :roles => [] }, t.options) end def test_remote_task_all_hosts_by_default util_set_hosts - t = @vlad.remote_task(:test_task) { 5 } + t = @rake.remote_task(:test_task) { 5 } assert_equal %w[app.example.com db.example.com], t.target_hosts end @@ -114,31 +113,31 @@ def test_remote_task_environment_override old_env_hosts = ENV["HOSTS"] ENV["HOSTS"] = 'other1.example.com, other2.example.com' util_set_hosts - t = @vlad.remote_task(:test_task) { 5 } + t = @rake.remote_task(:test_task) { 5 } assert_equal %w[other1.example.com other2.example.com], t.target_hosts - ensure + ensure ENV["HOSTS"] = old_env_hosts end def test_remote_task_body_set set(:some_variable, 5) - @vlad.host 'www.example.com', :app - @vlad.remote_task(:some_task) do $some_task_result = some_variable end + @rake.host 'www.example.com', :app + @rake.remote_task(:some_task) do $some_task_result = some_variable end Rake::Task['some_task'].execute nil - assert_equal @vlad.fetch(:some_variable), $some_task_result + assert_equal @rake.fetch(:some_variable), $some_task_result end def test_remote_task_with_options - t = @vlad.remote_task :test_task, :roles => [:app, :db] do + t = @rake.remote_task :test_task, :roles => [:app, :db] do fail "should not run" end assert_equal({:roles => [:app, :db]}, t.options) end def test_remote_task_before_host_declaration - t = @vlad.remote_task :test_task, :roles => :web do 5 end - @vlad.host 'www.example.com', :web + t = @rake.remote_task :test_task, :roles => :web do 5 end + @rake.host 'www.example.com', :web assert_equal %w[www.example.com], t.target_hosts end @@ -161,30 +160,30 @@ def test_remote_task_role_override def test_set set :win, 5 - assert_equal 5, @vlad.win + assert_equal 5, @rake.win end def test_set_lazy_block_evaluation set(:lose) { raise "lose" } - assert_raises(RuntimeError) { @vlad.lose } + assert_raises(RuntimeError) { @rake.lose } end def test_set_with_block x = 1 set(:win) { x += 2 } - assert_equal 3, @vlad.win - assert_equal 3, @vlad.win + assert_equal 3, @rake.win + assert_equal 3, @rake.win end def test_set_with_reference - @vlad.instance_eval do + @rake.instance_eval do set(:var_one) { var_two } set(:var_two) { var_three } set(:var_three) { 5 } end - assert_equal 5, @vlad.var_one + assert_equal 5, @rake.var_one end def test_set_with_block_and_value @@ -196,7 +195,7 @@ def test_set_with_block_and_value def test_set_with_nil set(:win, nil) - assert_equal nil, @vlad.win + assert_equal nil, @rake.win end def test_set_with_reserved_name diff --git a/test/test_vlad_subversion.rb b/test/test_vlad_subversion.rb index 6be74d2..9e54f70 100644 --- a/test/test_vlad_subversion.rb +++ b/test/test_vlad_subversion.rb @@ -1,8 +1,7 @@ -require 'vlad_test_case' require 'vlad' require 'vlad/subversion' -class TestVladSubversion < VladTestCase +class TestVladSubversion < MiniTest::Unit::TestCase def setup super @scm = Vlad::Subversion.new