Skip to content
This repository
Browse code

wip

  • Loading branch information...
commit 15ae8f59cf6f53fc09df53befa1204e175f117eb 1 parent 63b3726
authored January 06, 2012 deadlyicon committed January 06, 2012
15  Gemfile.lock
@@ -12,6 +12,7 @@ PATH
12 12
       json
13 13
       log4r
14 14
       open4
  15
+      popen4
15 16
       redis-namespace (~> 1)
16 17
       resque (~> 1.19.0)
17 18
       right_aws
@@ -24,6 +25,7 @@ PATH
24 25
 GEM
25 26
   remote: http://rubygems.org/
26 27
   specs:
  28
+    Platform (0.4.0)
27 29
     SystemTimer (1.2.3)
28 30
     actionpack (3.1.3)
29 31
       activemodel (= 3.1.3)
@@ -46,7 +48,7 @@ GEM
46 48
     childprocess (0.2.5)
47 49
       ffi (~> 1.0.6)
48 50
     columnize (0.3.5)
49  
-    daemons (1.1.4)
  51
+    daemons (1.1.5)
50 52
     diff-lcs (1.1.3)
51 53
     erubis (2.7.0)
52 54
     ffi (1.0.11)
@@ -56,17 +58,20 @@ GEM
56 58
     json (1.6.3)
57 59
     linecache (0.46)
58 60
       rbx-require-relative (> 0.0.4)
59  
-    log4r (1.1.9)
  61
+    log4r (1.1.10)
60 62
     macaddr (1.5.0)
61 63
       systemu (>= 2.4.0)
62 64
     multi_json (1.0.4)
63 65
     open4 (1.3.0)
  66
+    popen4 (0.1.2)
  67
+      Platform (>= 0.4.0)
  68
+      open4 (>= 0.4.0)
64 69
     rack (1.3.5)
65 70
     rack-cache (1.1)
66 71
       rack (>= 0.4)
67 72
     rack-mount (0.8.3)
68 73
       rack (>= 1.0.0)
69  
-    rack-protection (1.1.4)
  74
+    rack-protection (1.2.0)
70 75
       rack
71 76
     rack-test (0.6.1)
72 77
       rack (>= 1.0)
@@ -98,7 +103,7 @@ GEM
98 103
       ruby-debug-base (~> 0.10.4.0)
99 104
     ruby-debug-base (0.10.4)
100 105
       linecache (>= 0.3)
101  
-    sass (3.1.11)
  106
+    sass (3.1.12)
102 107
     shotgun (0.9)
103 108
       rack (>= 1.0)
104 109
     sinatra (1.3.1)
@@ -109,7 +114,7 @@ GEM
109 114
       hike (~> 1.2)
110 115
       rack (~> 1.0)
111 116
       tilt (~> 1.1, != 1.3.0)
112  
-    systemu (2.4.1)
  117
+    systemu (2.4.2)
113 118
     thor (0.14.6)
114 119
     tilt (1.3.3)
115 120
     uuid (2.3.4)
1  hobson.gemspec
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33 33
   s.add_runtime_dependency "right_aws"
34 34
   s.add_runtime_dependency "SystemTimer"
35 35
   s.add_runtime_dependency "childprocess"
  36
+  s.add_runtime_dependency "popen4"
36 37
   s.add_runtime_dependency "log4r"
37 38
   s.add_runtime_dependency "json"
38 39
   s.add_runtime_dependency "open4"
2  lib/hobson/bundler.rb
@@ -10,7 +10,7 @@ def self.with_clean_env
10 10
       ENV.delete("BUNDLE_GEMFILE")
11 11
       ENV["RUBYOPT"] = ENV["RUBYOPT"].gsub('-rbundler/setup', ' ') if ENV["RUBYOPT"]
12 12
 
13  
-      yield
  13
+      return yield
14 14
     }
15 15
   end
16 16
 
2  lib/hobson/cucumber/formatter.rb
@@ -11,7 +11,7 @@ class Formatter
11 11
       include ::Cucumber::Formatter::Io
12 12
 
13 13
       def initialize step_mother, path_or_io, options
14  
-        @io = ensure_io(path_or_io, "runtimes")
  14
+        @io = ensure_io(path_or_io, "hobson_status")
15 15
       end
16 16
 
17 17
       def before_feature feature
118  lib/hobson/project/workspace.rb
... ...
@@ -1,8 +1,10 @@
1 1
 require 'pathname'
  2
+require 'popen4'
  3
+require 'childprocess'
2 4
 
3 5
 class Hobson::Project::Workspace
4 6
 
5  
-  autoload :Execution, 'hobson/project/workspace/execution'
  7
+  # autoload :Execution, 'hobson/project/workspace/execution'
6 8
 
7 9
   attr_reader :project
8 10
 
@@ -19,14 +21,14 @@ def root
19 21
 
20 22
   def checkout! sha
21 23
     logger.info "checking out #{sha}"
22  
-    execute! "git fetch && git reset --hard #{sha} && git clean -df"
  24
+    execute "git fetch && git reset --hard #{sha} && git clean -df"
23 25
   end
24 26
 
25  
-  def ready?
  27
+  def exists?
26 28
     root.exist? && root.join('.git').directory?
27 29
   end
28 30
 
29  
-  def prepare!
  31
+  def create!
30 32
     root.parent.mkpath
31 33
     `git clone "#{project.url}" "#{root}"` or raise "unable to create workspace"
32 34
   end
@@ -48,7 +50,7 @@ def bundler
48 50
   end
49 51
 
50 52
   def prepare
51  
-    execute! 'bundle install' if bundler?
  53
+    execute 'bundle install' if bundler?
52 54
     root.join('log').mkpath
53 55
   end
54 56
 
@@ -58,14 +60,16 @@ def prepare
58 60
       --quiet
59 61
       --require features
60 62
       --require #{Hobson.lib.join('hobson/cucumber')}
61  
-      --format Hobson::Cucumber::Formatter
  63
+      --format pretty
62 64
       --format pretty --out log/cucumber
  65
+      --format Hobson::Cucumber::Formatter --out log/hobson_status
63 66
     ],
64 67
     'specs' => %W[
65 68
       rspec
66 69
       --require #{Hobson.lib.join('hobson/rspec')}
67  
-      --format Hobson::RSpec::Formatter
  70
+      --format documentation
68 71
       --format documentation --out log/rspec
  72
+      --format Hobson::RSpec::Formatter --out log/hobson_status
69 73
     ],
70 74
   }
71 75
 
@@ -82,90 +86,76 @@ def run_tests tests, &report_progress
82 86
     }
83 87
 
84 88
     # run each test type
85  
-    %w{features specs}.each{|type|
  89
+    %w{features specs test_units}.each{|type|
86 90
       next if tests[type].blank?
87 91
       logger.info "running #{type} tests"
88  
-      commands = bundler + TEST_COMMANDS[type] + tests[type]
89  
-      execute!(*commands) do |stdout, stderr|
90  
-        stdout.split("\n").each{|line|
  92
+
  93
+      command = "cd #{root.to_s.inspect} && "
  94
+      command << "bundle exec " if bundler?
  95
+      command << (TEST_COMMANDS[type] + tests[type]).join(' ')
  96
+      command << ">> log/hobson_#{type}.log"
  97
+
  98
+      logger.debug "command: #{command}"
  99
+
  100
+      file = root.join('log/hobson_status')
  101
+      FileUtils.touch(file)
  102
+      status = root.join('log/hobson_status').open
  103
+      process = ChildProcess.new(command)
  104
+      process.io.inherit!
  105
+
  106
+      update = proc{
  107
+        status.read.split("\n").each{|line|
91 108
           if line =~ /^TEST:([^:]+):(START|COMPLETE):(\d+)(?::(PASS|FAIL|PENDING))?$/
92 109
             report_progress.call($1, $2.downcase.to_sym, Time.at($3.to_i), $4)
93 110
           end
94 111
         }
  112
+      }
  113
+
  114
+      with_clean_env{ process.start }
  115
+      update.call while process.alive?
  116
+      update.call
  117
+      status.close
  118
+
  119
+      if process.crashed?
  120
+        raise ExecutionError, "#{command.inspect} crashed with exit code #{process.exit_code}"
95 121
       end
96 122
     }
  123
+    tests
97 124
   end
98 125
 
99 126
   ExecutionError = Class.new(StandardError)
100 127
 
101  
-  def execute! *args, &block
102  
-    execution = execute(*args, &block)
103  
-    if execution.failed?
104  
-      logger.error "COMMAND FAILED (#{execution.exit_code}) #{execution.args.inspect}"
105  
-      raise ExecutionError, "COMMAND: #{execution.args.inspect}\nEXIT: #{execution.exit_code}"
106  
-    end
107  
-    execution
108  
-  end
109  
-
110 128
   def execute *args, &block
111  
-    prepare! unless ready?
  129
+    create! unless exists?
112 130
 
113 131
     command = "cd #{root.to_s.inspect} && #{args.join(' ')}"
114 132
     command = "source #{rvm_source_file.inspect} && rvm rvmrc trust #{root.to_s.inspect} > /dev/null && #{command}" if rvm?
115 133
     command = "bash -lc #{command.inspect}"
116 134
 
117 135
     logger.info "executing: #{command.inspect}"
118  
-    execution = Execution.new(command, &block)
119 136
 
  137
+    with_clean_env{
  138
+      output = nil
  139
+      errors = nil
  140
+      status = POpen4::popen4(command){|stdout, stderr, stdin|
  141
+        output = stdout.read
  142
+        errors = stderr.read
  143
+      }
  144
+      raise ExecutionError, "#{command.inspect} could not be started" if status.nil?
  145
+      raise ExecutionError, "#{command.inspect} crashed with exit code #{$?.exitstatus}\n#{errors}" unless $?.success?
  146
+      return output
  147
+    }
  148
+  end
  149
+
  150
+  def with_clean_env &block
120 151
     Hobson::Bundler.with_clean_env{
121 152
       # TODO this should probably be somewhere better
122 153
       ENV['RAILS_ENV'] = 'test'
123 154
       ENV['DISPLAY'  ] = ':1'
124  
-      execution.start
125  
-    }
126  
-
127  
-    execution.read_loop{|out, err|
128  
-      logger.info "\n\n?????\n\n"
129  
-      logger.info  out if out.present?
130  
-      logger.error err if err.present?
131  
-      yield out, err if block_given?
  155
+      return yield
132 156
     }
133 157
   end
134 158
 
135  
-
136  
-  #   process = ChildProcess.new(command)
137  
-  #   process.io.stdout = Tempfile.new("hobson_exec")
138  
-  #   process.io.stderr = Tempfile.new("hobson_exec")
139  
-  #   stdout = File.open(process.io.stdout.path)
140  
-  #   stderr = File.open(process.io.stderr.path)
141  
-
142  
-  #   Hobson::Bundler.with_clean_env{
143  
-  #     # TODO this should probably be somewhere better
144  
-  #     ENV['RAILS_ENV'] = 'test'
145  
-  #     ENV['DISPLAY'  ] = ':1'
146  
-  #     process.start
147  
-  #   }
148  
-
149  
-  #   read = proc do
150  
-  #     out, err = stdout.read, stderr.read
151  
-  #     logger.debug out if out.present?
152  
-  #     logger.debug err if err.present?
153  
-  #     if (out+err).include?('Segmentation fault')
154  
-  #       raise ExecutionError, "#{cmd}\n\n#{out}\n#{err}"
155  
-  #     end
156  
-  #     yield out, err if block_given?
157  
-  #   end
158  
-
159  
-  #   while process.alive?
160  
-  #     read.call
161  
-  #     sleep 0.25
162  
-  #   end
163  
-
164  
-  #   read.call
165  
-
166  
-  #   process
167  
-  # end
168  
-
169 159
   def inspect
170 160
     "#<#{self.class} project:#{project.name} root:#{root}>"
171 161
   end
112  lib/hobson/project/workspace/execution.rb
... ...
@@ -1,71 +1,71 @@
1  
-require 'childprocess'
2  
-require 'tempfile'
  1
+# require 'childprocess'
  2
+# require 'tempfile'
3 3
 
4  
-class Hobson::Project::Workspace::Execution
  4
+# class Hobson::Project::Workspace::Execution
5 5
 
6  
-  attr_reader :process, :stdout, :stderr, :stdout_file, :stderr_file
  6
+#   attr_reader :process, :stdout, :stderr, :stdout_file, :stderr_file
7 7
 
8  
-  def initialize *args, &block
9  
-    @process     = ChildProcess.new(*args)
10  
-    @stdout      = ""
11  
-    @stderr      = ""
12  
-    @stdout_file = File.open((@process.io.stdout = tempfile).path)
13  
-    @stderr_file = File.open((@process.io.stderr = tempfile).path)
14  
-    read_loop(&block) if block_given?
15  
-  end
  8
+#   def initialize *args, &block
  9
+#     @process     = ChildProcess.new(*args)
  10
+#     @stdout      = ""
  11
+#     @stderr      = ""
  12
+#     @stdout_file = File.open((@process.io.stdout = tempfile).path)
  13
+#     @stderr_file = File.open((@process.io.stderr = tempfile).path)
  14
+#     read_loop(&block) if block_given?
  15
+#   end
16 16
 
17  
-  def start
18  
-    process.start unless started?
19  
-  end
  17
+#   def start
  18
+#     process.start unless started?
  19
+#   end
20 20
 
21  
-  def read_loop &block
22  
-    start unless started?
23  
-    while process.alive?
24  
-      read(&block)
25  
-      sleep 0.1
26  
-    end
27  
-    read(&block)
28  
-    self
29  
-  end
  21
+#   def read_loop &block
  22
+#     start unless started?
  23
+#     while process.alive?
  24
+#       read(&block)
  25
+#       sleep 0.1
  26
+#     end
  27
+#     read(&block)
  28
+#     self
  29
+#   end
30 30
 
31  
-  def read &block
32  
-    out, err = @stdout_file.read, @stderr_file.read
33  
-    @stdout += out
34  
-    @stderr += err
35  
-    yield out, err if block_given? && (out != "" || err != "")
36  
-    [out, err]
37  
-  end
  31
+#   def read &block
  32
+#     out, err = @stdout_file.read, @stderr_file.read
  33
+#     @stdout += out
  34
+#     @stderr += err
  35
+#     yield out, err if block_given? && (out != "" || err != "")
  36
+#     [out, err]
  37
+#   end
38 38
 
39  
-  def exit_code
40  
-    process.exited?
41  
-    process.exit_code
42  
-  end
  39
+#   def exit_code
  40
+#     process.exited?
  41
+#     process.exit_code
  42
+#   end
43 43
 
44  
-  def success?
45  
-    exit_code == 0 if exited?
46  
-  end
  44
+#   def success?
  45
+#     exit_code == 0 if exited?
  46
+#   end
47 47
 
48  
-  def failed?
49  
-    !success?
50  
-  end
  48
+#   def failed?
  49
+#     !success?
  50
+#   end
51 51
 
52  
-  def args
53  
-    process.instance_variable_get(:@args)
54  
-  end
  52
+#   def args
  53
+#     process.instance_variable_get(:@args)
  54
+#   end
55 55
 
56  
-  def inspect
57  
-    "#<#{self.class} #{args.inspect}>"
58  
-  end
59  
-  alias_method :to_s, :inspect
  56
+#   def inspect
  57
+#     "#<#{self.class} #{args.inspect}>"
  58
+#   end
  59
+#   alias_method :to_s, :inspect
60 60
 
61  
-  private
  61
+#   private
62 62
 
63  
-  def tempfile
64  
-    Tempfile.new('hobson')
65  
-  end
  63
+#   def tempfile
  64
+#     Tempfile.new('hobson')
  65
+#   end
66 66
 
67  
-  # delegate all public process methods that we dont have to process
68  
-  delegate(*((ChildProcess.new.public_methods - instance_methods) + [{:to => :process}]))
69  
-  delegate :started?, :to => :process
  67
+#   # delegate all public process methods that we dont have to process
  68
+#   delegate(*((ChildProcess.new.public_methods - instance_methods) + [{:to => :process}]))
  69
+#   delegate :started?, :to => :process
70 70
 
71  
-end
  71
+# end
27  lib/hobson/rspec/formatter.rb
@@ -11,7 +11,7 @@
11 11
 
12 12
   config.before :all do
13 13
     spec = get_spec.call(self)
14  
-    puts "TEST:#{spec}:START:#{Time.now.to_i}"
  14
+    Hobson::RSpec::Formatter.puts "TEST:#{spec}:START:#{Time.now.to_i}"
15 15
   end
16 16
 
17 17
   config.after :all do
@@ -24,17 +24,36 @@
24 24
       'FAIL' : 'PASS'
25 25
     end
26 26
 
27  
-    puts "TEST:#{spec}:COMPLETE:#{Time.now.to_i}:#{status}"
  27
+    Hobson::RSpec::Formatter.puts "TEST:#{spec}:COMPLETE:#{Time.now.to_i}:#{status}"
28 28
   end
29 29
 
30 30
 end
31 31
 
  32
+
  33
+
32 34
 module Hobson
33 35
   module RSpec
34 36
     class Formatter < ::RSpec::Core::Formatters::BaseFormatter
35  
-      def initialize output
36  
-        super StringIO.new
  37
+
  38
+      def self.instances
  39
+        @@instances ||= []
  40
+      end
  41
+
  42
+      def self.puts *args
  43
+        instances.each{|instance|
  44
+          instance.io.puts *args
  45
+          instance.io.flush
  46
+        }
37 47
       end
  48
+
  49
+      attr_accessor :io
  50
+
  51
+      def initialize io
  52
+        super
  53
+        @io = io
  54
+        self.class.instances << self
  55
+      end
  56
+
38 57
     end
39 58
   end
40 59
 end

0 notes on commit 15ae8f5

Please sign in to comment.
Something went wrong with that request. Please try again.