gorgon 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +52 -0
- data/README.md +53 -0
- data/Rakefile +1 -0
- data/bin/gorgon +41 -0
- data/gorgon.gemspec +33 -0
- data/lib/gorgon.rb +6 -0
- data/lib/gorgon/amqp_service.rb +39 -0
- data/lib/gorgon/callback_handler.rb +21 -0
- data/lib/gorgon/configuration.rb +9 -0
- data/lib/gorgon/failures_printer.rb +37 -0
- data/lib/gorgon/g_logger.rb +22 -0
- data/lib/gorgon/host_state.rb +31 -0
- data/lib/gorgon/job.rb +26 -0
- data/lib/gorgon/job_definition.rb +24 -0
- data/lib/gorgon/job_state.rb +119 -0
- data/lib/gorgon/listener.rb +147 -0
- data/lib/gorgon/originator.rb +120 -0
- data/lib/gorgon/originator_logger.rb +36 -0
- data/lib/gorgon/originator_protocol.rb +65 -0
- data/lib/gorgon/pipe_manager.rb +55 -0
- data/lib/gorgon/progress_bar_view.rb +121 -0
- data/lib/gorgon/source_tree_syncer.rb +37 -0
- data/lib/gorgon/testunit_runner.rb +50 -0
- data/lib/gorgon/version.rb +3 -0
- data/lib/gorgon/worker.rb +103 -0
- data/lib/gorgon/worker_manager.rb +148 -0
- data/lib/gorgon/worker_watcher.rb +22 -0
- data/spec/callback_handler_spec.rb +77 -0
- data/spec/failures_printer_spec.rb +66 -0
- data/spec/host_state_spec.rb +65 -0
- data/spec/job_definition_spec.rb +20 -0
- data/spec/job_state_spec.rb +231 -0
- data/spec/listener_spec.rb +194 -0
- data/spec/originator_logger_spec.rb +40 -0
- data/spec/originator_protocol_spec.rb +134 -0
- data/spec/originator_spec.rb +134 -0
- data/spec/progress_bar_view_spec.rb +98 -0
- data/spec/source_tree_syncer_spec.rb +65 -0
- data/spec/worker_manager_spec.rb +23 -0
- data/spec/worker_spec.rb +114 -0
- metadata +270 -0
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            require 'gorgon/originator_logger'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe OriginatorLogger do
         | 
| 4 | 
            +
              before do
         | 
| 5 | 
            +
                OriginatorLogger.any_instance.stub(:initialize_logger)
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let (:originator_logger) { OriginatorLogger.new "" }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              describe "#log_message" do
         | 
| 11 | 
            +
                it "prints start messages" do
         | 
| 12 | 
            +
                  payload = {:action => "start",
         | 
| 13 | 
            +
                             :hostname => "host",
         | 
| 14 | 
            +
                             :filename => "filename"}
         | 
| 15 | 
            +
                  originator_logger.should_receive(:log).with("Started running 'filename' at 'host'")
         | 
| 16 | 
            +
                  originator_logger.log_message(payload)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                it "prints finish messages" do
         | 
| 20 | 
            +
                  payload = {:action => "finish",
         | 
| 21 | 
            +
                             :hostname => "host",
         | 
| 22 | 
            +
                             :filename => "filename"}
         | 
| 23 | 
            +
                  originator_logger.should_receive(:log).with("Finished running 'filename' at 'host'")
         | 
| 24 | 
            +
                  originator_logger.log_message(payload)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it "prints failure messages when a test finishes with failures" do
         | 
| 28 | 
            +
                  payload = {:action => "finish",
         | 
| 29 | 
            +
                             :type => "fail",
         | 
| 30 | 
            +
                             :hostname => "host",
         | 
| 31 | 
            +
                             :filename => "filename",
         | 
| 32 | 
            +
                             :failures => [
         | 
| 33 | 
            +
                               "failure"
         | 
| 34 | 
            +
                             ]}
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  originator_logger.should_receive(:log).with("Finished running 'filename' at 'host'failure\n")
         | 
| 37 | 
            +
                  originator_logger.log_message(payload)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,134 @@ | |
| 1 | 
            +
            require 'gorgon/originator_protocol'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe OriginatorProtocol do
         | 
| 4 | 
            +
              let(:connection) { stub("Connection", :disconnect => nil, :on_closed => nil)}
         | 
| 5 | 
            +
              let(:queue) { stub("Queue", :bind => nil, :subscribe => nil, :name => "queue", :purge => nil,
         | 
| 6 | 
            +
                                 :delete => nil) }
         | 
| 7 | 
            +
              let(:exchange) { stub("Exchange", :publish => nil, :name => "exchange") }
         | 
| 8 | 
            +
              let(:channel) { stub("Channel", :queue => queue, :direct => exchange, :fanout => exchange,
         | 
| 9 | 
            +
                                   :default_exchange => exchange) }
         | 
| 10 | 
            +
              let(:logger){ stub("Logger", :log => nil)}
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              before do
         | 
| 13 | 
            +
                AMQP.stub!(:connect).and_return connection
         | 
| 14 | 
            +
                AMQP::Channel.stub!(:new).and_return channel
         | 
| 15 | 
            +
                @originator_p = OriginatorProtocol.new logger
         | 
| 16 | 
            +
                @conn_information = {:host => "host"}
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              describe "#connect" do
         | 
| 20 | 
            +
                it "opens AMQP connection" do
         | 
| 21 | 
            +
                  AMQP.should_receive(:connect).with(@conn_information)
         | 
| 22 | 
            +
                  @originator_p.connect(@conn_information)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                it "opens a new channel" do
         | 
| 26 | 
            +
                  AMQP::Channel.should_receive(:new).with(connection)
         | 
| 27 | 
            +
                  @originator_p.connect @conn_information
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                it "sets Connection#on_close callbacks" do
         | 
| 31 | 
            +
                  on_disconnect_called = false
         | 
| 32 | 
            +
                  on_disconnect = Proc.new { on_disconnect_called = true }
         | 
| 33 | 
            +
                  connection.should_receive(:on_closed).and_yield
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  @originator_p.connect @conn_information, :on_closed => on_disconnect
         | 
| 36 | 
            +
                  @originator_p.disconnect
         | 
| 37 | 
            +
                  on_disconnect_called.should be_true
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it "opens a reply and exchange queue" do
         | 
| 41 | 
            +
                  UUIDTools::UUID.stub!(:timestamp_create).and_return 1
         | 
| 42 | 
            +
                  channel.should_receive(:queue).twice.with("1")
         | 
| 43 | 
            +
                  @originator_p.connect @conn_information
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                it "opens a reply exchange and binds reply queue to it" do
         | 
| 47 | 
            +
                  UUIDTools::UUID.stub!(:timestamp_create).and_return 1
         | 
| 48 | 
            +
                  channel.should_receive(:direct).with("1")
         | 
| 49 | 
            +
                  queue.should_receive(:bind).with(exchange)
         | 
| 50 | 
            +
                  @originator_p.connect @conn_information
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              describe "#publish_files" do
         | 
| 55 | 
            +
                before do
         | 
| 56 | 
            +
                  @originator_p.connect @conn_information
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                it "publish each file using channel's default_exchange" do
         | 
| 60 | 
            +
                  files = ["file1", "file2"]
         | 
| 61 | 
            +
                  channel.should_receive(:default_exchange)
         | 
| 62 | 
            +
                  exchange.should_receive(:publish).once.ordered.with("file1", :routing_key => "queue")
         | 
| 63 | 
            +
                  exchange.should_receive(:publish).once.ordered.with("file2", :routing_key => "queue")
         | 
| 64 | 
            +
                  @originator_p.publish_files files
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              describe "#publish_job" do
         | 
| 69 | 
            +
                before do
         | 
| 70 | 
            +
                  @originator_p.connect @conn_information
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                it "add queue's names to job_definition and fanout using 'gorgon.jobs' exchange" do
         | 
| 74 | 
            +
                  channel.should_receive(:fanout).with("gorgon.jobs")
         | 
| 75 | 
            +
                  exp_job_definition = JobDefinition.new
         | 
| 76 | 
            +
                  exp_job_definition.file_queue_name = "queue"
         | 
| 77 | 
            +
                  exp_job_definition.reply_exchange_name = "exchange"
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  exchange.should_receive(:publish).with(exp_job_definition.to_json)
         | 
| 80 | 
            +
                  @originator_p.publish_job JobDefinition.new
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              describe "#receive_payloads" do
         | 
| 85 | 
            +
                before do
         | 
| 86 | 
            +
                  @originator_p.connect @conn_information
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                it "subscribe to reply_queue and yield payload" do
         | 
| 90 | 
            +
                  payload = {:key => "info"}
         | 
| 91 | 
            +
                  queue.should_receive(:subscribe).and_yield(payload)
         | 
| 92 | 
            +
                  yielded = false
         | 
| 93 | 
            +
                  @originator_p.receive_payloads do |p|
         | 
| 94 | 
            +
                    yielded = true
         | 
| 95 | 
            +
                    p.should == payload
         | 
| 96 | 
            +
                  end
         | 
| 97 | 
            +
                  yielded.should be_true
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              describe "#cancel_job" do
         | 
| 102 | 
            +
                before do
         | 
| 103 | 
            +
                  @originator_p.connect @conn_information
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                it "purges file_queue" do
         | 
| 107 | 
            +
                  queue.should_receive(:purge)
         | 
| 108 | 
            +
                  @originator_p.cancel_job
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                it "fanout 'cancel' message using 'gorgon.worker_managers' exchange" do
         | 
| 112 | 
            +
                  msg = Yajl::Encoder.encode({:action => "cancel_job"})
         | 
| 113 | 
            +
                  channel.should_receive(:fanout).with("gorgon.worker_managers")
         | 
| 114 | 
            +
                  exchange.should_receive(:publish).with(msg)
         | 
| 115 | 
            +
                  @originator_p.cancel_job
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
              end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
              describe "#disconnect" do
         | 
| 120 | 
            +
                before do
         | 
| 121 | 
            +
                  @originator_p.connect @conn_information
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                it "deletes reply and file queue" do
         | 
| 125 | 
            +
                  queue.should_receive(:delete).twice
         | 
| 126 | 
            +
                  @originator_p.disconnect
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                it "disconnects connection" do
         | 
| 130 | 
            +
                  connection.should_receive(:disconnect)
         | 
| 131 | 
            +
                  @originator_p.disconnect
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
              end
         | 
| 134 | 
            +
            end
         | 
| @@ -0,0 +1,134 @@ | |
| 1 | 
            +
            require 'gorgon/originator'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Originator do
         | 
| 4 | 
            +
              let(:protocol){ stub("Originator Protocol", :connect => nil, :publish_files => nil,
         | 
| 5 | 
            +
                                   :publish_job => nil, :receive_payloads => nil, :cancel_job => nil,
         | 
| 6 | 
            +
                                   :disconnect => nil)}
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let(:configuration){ {:files => ["some/file"]}}
         | 
| 9 | 
            +
              let(:job_state){ stub("JobState", :is_job_complete? => false, :file_finished => nil,
         | 
| 10 | 
            +
                                    :add_observer => nil)}
         | 
| 11 | 
            +
              let(:progress_bar_view){ stub("Progress Bar View", :show => nil)}
         | 
| 12 | 
            +
              let(:originator_logger){ stub("Originator Logger", :log => nil, :log_message => nil)}
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              before do
         | 
| 15 | 
            +
                OriginatorLogger.stub(:new).and_return originator_logger
         | 
| 16 | 
            +
                @originator = Originator.new
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              describe "#publish_job" do
         | 
| 20 | 
            +
                before do
         | 
| 21 | 
            +
                  stub_methods
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                it "creates a JobState instance and passes total files" do
         | 
| 25 | 
            +
                  @originator.stub!(:files).and_return ["a file", "other file"]
         | 
| 26 | 
            +
                  JobState.should_receive(:new).with(2).and_return job_state
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  @originator.publish
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                it "creates a ProgressBarView and show" do
         | 
| 32 | 
            +
                  JobState.stub!(:new).and_return job_state
         | 
| 33 | 
            +
                  ProgressBarView.should_receive(:new).with(job_state).and_return progress_bar_view
         | 
| 34 | 
            +
                  progress_bar_view.should_receive(:show)
         | 
| 35 | 
            +
                  @originator.publish
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              describe "#cancel_job" do
         | 
| 40 | 
            +
                before do
         | 
| 41 | 
            +
                  stub_methods
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it "call JobState#cancel" do
         | 
| 45 | 
            +
                  JobState.stub!(:new).and_return job_state
         | 
| 46 | 
            +
                  job_state.should_receive(:cancel)
         | 
| 47 | 
            +
                  @originator.publish
         | 
| 48 | 
            +
                  @originator.cancel_job
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                it "tells @protocol to cancel job and disconnect" do
         | 
| 52 | 
            +
                  protocol.should_receive(:cancel_job)
         | 
| 53 | 
            +
                  protocol.should_receive(:disconnect)
         | 
| 54 | 
            +
                  @originator.publish
         | 
| 55 | 
            +
                  @originator.cancel_job
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              describe "#cleanup_if_job_complete" do
         | 
| 60 | 
            +
                before do
         | 
| 61 | 
            +
                  stub_methods
         | 
| 62 | 
            +
                  JobState.stub!(:new).and_return job_state
         | 
| 63 | 
            +
                  @originator.publish
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                it "calls JobState#is_job_complete?" do
         | 
| 67 | 
            +
                  job_state.should_receive(:is_job_complete?).and_return false
         | 
| 68 | 
            +
                  @originator.cleanup_if_job_complete
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                it "disconnect if job is complete" do
         | 
| 72 | 
            +
                  job_state.stub!(:is_job_complete?).and_return true
         | 
| 73 | 
            +
                  protocol.should_receive(:disconnect)
         | 
| 74 | 
            +
                  @originator.cleanup_if_job_complete
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              describe "#handle_reply" do
         | 
| 79 | 
            +
                before do
         | 
| 80 | 
            +
                  stub_methods
         | 
| 81 | 
            +
                  JobState.stub!(:new).and_return job_state
         | 
| 82 | 
            +
                  @originator.publish
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                it "calls cleanup_if_job_complete" do
         | 
| 86 | 
            +
                  @originator.should_receive(:cleanup_if_job_complete)
         | 
| 87 | 
            +
                  @originator.handle_reply finish_payload
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                it "calls JobState#file_started if payload[:action] is 'start'" do
         | 
| 91 | 
            +
                  payload = Yajl::Parser.new(:symbolize_keys => true).parse(start_payload)
         | 
| 92 | 
            +
                  job_state.should_receive(:file_started)
         | 
| 93 | 
            +
                  @originator.handle_reply(start_payload)
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                it "calls JobState#file_finished if payload[:action] is 'finish'" do
         | 
| 97 | 
            +
                  payload = Yajl::Parser.new(:symbolize_keys => true).parse(finish_payload)
         | 
| 98 | 
            +
                  job_state.should_receive(:file_finished).with(payload)
         | 
| 99 | 
            +
                  @originator.handle_reply(finish_payload)
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              private
         | 
| 104 | 
            +
             | 
| 105 | 
            +
              def stub_methods
         | 
| 106 | 
            +
                EventMachine.stub!(:run).and_yield
         | 
| 107 | 
            +
                ProgressBarView.stub!(:new).and_return progress_bar_view
         | 
| 108 | 
            +
                OriginatorProtocol.stub!(:new).and_return protocol
         | 
| 109 | 
            +
                @originator.stub!(:configuration).and_return configuration
         | 
| 110 | 
            +
                @originator.stub!(:connection_information).and_return 'host'
         | 
| 111 | 
            +
                @originator.stub!(:job_definition).and_return JobDefinition.new
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
              def start_payload
         | 
| 115 | 
            +
                '{
         | 
| 116 | 
            +
                  "action": "start",
         | 
| 117 | 
            +
                  "hostname": "host",
         | 
| 118 | 
            +
                  "worker_id": "1",
         | 
| 119 | 
            +
                  "filename": "test/file_test.rb"
         | 
| 120 | 
            +
                }'
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
              def finish_payload
         | 
| 124 | 
            +
                '{
         | 
| 125 | 
            +
                  "action": "finish",
         | 
| 126 | 
            +
                  "hostname": "host",
         | 
| 127 | 
            +
                  "worker_id": "1",
         | 
| 128 | 
            +
                  "filename": "test/file_test.rb",
         | 
| 129 | 
            +
                  "failures": [],
         | 
| 130 | 
            +
                  "type": "pass",
         | 
| 131 | 
            +
                  "time": 3
         | 
| 132 | 
            +
                }'
         | 
| 133 | 
            +
              end
         | 
| 134 | 
            +
            end
         | 
| @@ -0,0 +1,98 @@ | |
| 1 | 
            +
            require 'gorgon/progress_bar_view'
         | 
| 2 | 
            +
            require 'gorgon/job_state'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe ProgressBarView do
         | 
| 5 | 
            +
              describe "#initialize" do
         | 
| 6 | 
            +
                it "adds itself to observers of job_state" do
         | 
| 7 | 
            +
                  job_state = JobState.new 1
         | 
| 8 | 
            +
                  job_state.should_receive(:add_observer)
         | 
| 9 | 
            +
                  ProgressBarView.new job_state
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              describe "#show" do
         | 
| 14 | 
            +
                before do
         | 
| 15 | 
            +
                  job_state = JobState.new 1
         | 
| 16 | 
            +
                  @progress_bar_view = ProgressBarView.new job_state
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                it "prints a message in console saying that is loading workers" do
         | 
| 20 | 
            +
                  $stdout.should_receive(:write).with(/loading .*workers/i)
         | 
| 21 | 
            +
                  ProgressBar.should_not_receive(:create)
         | 
| 22 | 
            +
                  @progress_bar_view.show
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              describe "#update" do
         | 
| 27 | 
            +
                let(:progress_bar) { stub("Progress Bar", :title= => nil, :progress= => nil, :format => nil,
         | 
| 28 | 
            +
                                          :finished? => false)}
         | 
| 29 | 
            +
                let(:payload) {
         | 
| 30 | 
            +
                  { :filename => "path/file.rb",
         | 
| 31 | 
            +
                    :hostname => "host",
         | 
| 32 | 
            +
                    :failures => ["Failure messages"]}
         | 
| 33 | 
            +
                }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                before do
         | 
| 36 | 
            +
                  ProgressBar.stub!(:create).and_return progress_bar
         | 
| 37 | 
            +
                  @job_state = JobState.new 2
         | 
| 38 | 
            +
                  @job_state.stub!(:state).and_return :running
         | 
| 39 | 
            +
                  @progress_bar_view = ProgressBarView.new @job_state
         | 
| 40 | 
            +
                  $stdout.stub!(:write)
         | 
| 41 | 
            +
                  @progress_bar_view.show
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it "doesn't create ProgressBar if JobState is not running" do
         | 
| 45 | 
            +
                  @job_state.should_receive(:state).and_return :starting
         | 
| 46 | 
            +
                  ProgressBar.should_not_receive(:create).with(hash_including(:total => 2))
         | 
| 47 | 
            +
                  @progress_bar_view.update
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                it "doesn't create a ProgressBar if one was already created" do
         | 
| 51 | 
            +
                  @progress_bar_view.update
         | 
| 52 | 
            +
                  ProgressBar.should_not_receive(:create).with(hash_including(:total => 2))
         | 
| 53 | 
            +
                  @progress_bar_view.update
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                it "gets total files from JobState and create a ProgressBar once JobState is running" do
         | 
| 57 | 
            +
                  ProgressBar.should_receive(:create).with(hash_including(:total => 2))
         | 
| 58 | 
            +
                  @progress_bar_view.update
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                it "gets finished_files_count" do
         | 
| 62 | 
            +
                  @job_state.should_receive :finished_files_count
         | 
| 63 | 
            +
                  @progress_bar_view.update
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                it "gets failed_files_count" do
         | 
| 67 | 
            +
                  @job_state.should_receive(:failed_files_count).and_return 0
         | 
| 68 | 
            +
                  @progress_bar_view.update
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                it "prints failures and finish progress_bar when job is done" do
         | 
| 72 | 
            +
                  @progress_bar_view.update
         | 
| 73 | 
            +
                  @job_state.stub!(:each_failed_test).and_yield(payload)
         | 
| 74 | 
            +
                  @job_state.stub!(:is_job_complete?).and_return :true
         | 
| 75 | 
            +
                  $stdout.should_receive(:write).with(/Failure messages/)
         | 
| 76 | 
            +
                  @progress_bar_view.update
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                context "when job is cancelled" do
         | 
| 80 | 
            +
                  before do
         | 
| 81 | 
            +
                    @progress_bar_view.update
         | 
| 82 | 
            +
                    @job_state.stub!(:is_job_cancelled?).and_return :true
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  it "prints failures and finish progress_bar when job is cancelled" do
         | 
| 86 | 
            +
                    @job_state.stub!(:each_failed_test).and_yield(payload)
         | 
| 87 | 
            +
                    $stdout.should_receive(:write).with(/Failure messages/)
         | 
| 88 | 
            +
                    @progress_bar_view.update
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  it "prints files that were running when the job was cancelled" do
         | 
| 92 | 
            +
                    @job_state.should_receive(:each_running_file).and_yield("hostname", "file1.rb")
         | 
| 93 | 
            +
                    $stdout.should_receive(:write).with(/file1\.rb.*hostname/)
         | 
| 94 | 
            +
                    @progress_bar_view.update
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
| @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            require 'gorgon/source_tree_syncer'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe SourceTreeSyncer.new("") do
         | 
| 4 | 
            +
              it { should respond_to :exclude= }
         | 
| 5 | 
            +
              it { should respond_to :sync }
         | 
| 6 | 
            +
              it { should respond_to :sys_command }
         | 
| 7 | 
            +
              it { should respond_to :remove_temp_dir }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              describe "#sync" do
         | 
| 10 | 
            +
                before do
         | 
| 11 | 
            +
                  @syncer = SourceTreeSyncer.new "path/to/source"
         | 
| 12 | 
            +
                  stub_utilities_methods
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                it "makes tempdir and changes current dir to temdir" do
         | 
| 16 | 
            +
                  Dir.should_receive(:mktmpdir).and_return("tmp/dir")
         | 
| 17 | 
            +
                  Dir.should_receive(:chdir).with("tmp/dir")
         | 
| 18 | 
            +
                  @syncer.sync
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                it "runs rsync system command with appropriate options" do
         | 
| 22 | 
            +
                  cmd = /rsync.*-az.*-r --rsh=ssh path\/to\/source\/\* \./
         | 
| 23 | 
            +
                  @syncer.should_receive(:system).with(cmd)
         | 
| 24 | 
            +
                  @syncer.sync
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it "exclude files when they are specified" do
         | 
| 28 | 
            +
                  @syncer.exclude = ["log", ".git"]
         | 
| 29 | 
            +
                  @syncer.should_receive(:system).with(/--exclude log --exclude .git/)
         | 
| 30 | 
            +
                  @syncer.sync
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it "returns true if sys command execution was successful" do
         | 
| 34 | 
            +
                  $?.stub!(:exitstatus).and_return 0
         | 
| 35 | 
            +
                  @syncer.sync.should be_true
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                it "returns false if sys command execution failed" do
         | 
| 39 | 
            +
                  $?.stub!(:exitstatus).and_return 1
         | 
| 40 | 
            +
                  @syncer.sync.should be_false
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              describe "#remove_temp_dir" do
         | 
| 45 | 
            +
                before do
         | 
| 46 | 
            +
                  @syncer = SourceTreeSyncer.new "path/to/source"
         | 
| 47 | 
            +
                  stub_utilities_methods
         | 
| 48 | 
            +
                  @syncer.sync
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                it "remove temporary dir" do
         | 
| 52 | 
            +
                  FileUtils.should_receive(:remove_entry_secure).with("tmp/dir")
         | 
| 53 | 
            +
                  @syncer.remove_temp_dir
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              private
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              def stub_utilities_methods
         | 
| 60 | 
            +
                Dir.stub!(:mktmpdir).and_return("tmp/dir")
         | 
| 61 | 
            +
                Dir.stub!(:chdir)
         | 
| 62 | 
            +
                FileUtils.stub!(:remove_entry_secure)
         | 
| 63 | 
            +
                @syncer.stub!(:system)
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         |