Class: ASAutotest::TestRunner

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/asautotest/test-runner.rb

Defined Under Namespace

Classes: Result, Suite, TestMisbehaving, TestMisbehavingFatally

Constant Summary collapse

EXPECTED_GREETING =
"Hello, this is a test.\n"
POLICY_FILE_REQUEST =
"<policy-file-request/>\0"

Constants included from Logging

Logging::PREFIX

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

#barf, #end_saying, #end_whisper, #hint, #new_logging_section, #say, #say_with_block, #say_without_block, #shout, #start_saying, #start_whisper, verbose=, verbose?, #verbose?, #whisper, #whisper_with_block, #whisper_without_block

Constructor Details

#initialize(binary_name, port) ⇒ TestRunner

Returns a new instance of TestRunner.



38
39
40
41
42
43
# File 'lib/asautotest/test-runner.rb', line 38

def initialize(binary_name, port)
  @binary_name = binary_name
  @port = port
  @n_planned_tests = nil
  @suites = {}
end

Instance Attribute Details

#n_planned_testsObject (readonly)




402
403
404
# File 'lib/asautotest/test-runner.rb', line 402

def n_planned_tests
  @n_planned_tests
end

Instance Method Details

#accept_connectionObject




122
123
124
125
126
127
128
129
# File 'lib/asautotest/test-runner.rb', line 122

def accept_connection
  whisper "Accepting connection" do
    # It takes at least 3 seconds to get a policy file request.
    @socket = Timeout.timeout(4) { @server.accept }
  end
rescue Timeout::Error
  misbehavior! "Test did not connect to localhost:#@port."
end

#failed_tests?Boolean

Returns:

  • (Boolean)


420
421
422
# File 'lib/asautotest/test-runner.rb', line 420

def failed_tests?
  n_failed_tests > 0
end

#fatal_misbehavior!(*descriptions) ⇒ Object



109
110
111
112
# File 'lib/asautotest/test-runner.rb', line 109

def fatal_misbehavior!(*descriptions)
  print_warnings(descriptions)
  raise TestMisbehavingFatally
end

#get_suite(name) ⇒ Object



231
232
233
234
235
236
237
# File 'lib/asautotest/test-runner.rb', line 231

def get_suite(name)
  if @suites.include? name
    @suites[name]
  else
    @suites[name] = Suite.new(name)
  end
end

#misbehavior!(*descriptions) ⇒ Object


Raises:



104
105
106
107
# File 'lib/asautotest/test-runner.rb', line 104

def misbehavior!(*descriptions)
  print_warnings(descriptions)
  raise TestMisbehaving
end

#missing_tests?Boolean

Returns:

  • (Boolean)


416
417
418
# File 'lib/asautotest/test-runner.rb', line 416

def missing_tests?
  n_missing_tests > 0
end

#n_completed_testsObject



219
220
221
# File 'lib/asautotest/test-runner.rb', line 219

def n_completed_tests
  suites.map(&:n_results).sum
end

#n_failed_testsObject



223
224
225
# File 'lib/asautotest/test-runner.rb', line 223

def n_failed_tests
  suites.map(&:n_failures).sum
end

#n_missing_testsObject



404
405
406
# File 'lib/asautotest/test-runner.rb', line 404

def n_missing_tests
  n_planned_tests - n_completed_tests
end

#n_new_testsObject



408
409
410
# File 'lib/asautotest/test-runner.rb', line 408

def n_new_tests
  n_completed_tests - n_planned_tests
end

#new_tests?Boolean

Returns:

  • (Boolean)


412
413
414
# File 'lib/asautotest/test-runner.rb', line 412

def new_tests?
  n_new_tests > 0
end

#parse_greeting(greeting) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/asautotest/test-runner.rb', line 141

def parse_greeting(greeting)
  case greeting
  when EXPECTED_GREETING
    whisper "Performed handshake."
  when nil
    misbehavior! "Test closed connection without sending anything."
  when POLICY_FILE_REQUEST
    fatal_misbehavior! \
      "Received cross-domain policy file request; aborting.",
      "Please run a policy server on port 843 (root usually needed).",
      "See ‘bin/policy-server.rb’ in the ASAutotest distribution."
  else
    misbehavior! "Unrecognized greeting: #{greeting.inspect}"
  end
end


114
115
116
117
118
# File 'lib/asautotest/test-runner.rb', line 114

def print_warnings(warnings)
  for warning in warnings do
    shout warning
  end
end

#read_greetingObject



137
138
139
# File 'lib/asautotest/test-runner.rb', line 137

def read_greeting
  @socket.read(EXPECTED_GREETING.size)
end

#report_resultsObject



165
166
167
168
169
170
171
172
173
# File 'lib/asautotest/test-runner.rb', line 165

def report_results
  if failed_tests?
    suites.each &:print_report!
    puts
  else
    say test_count_report
    shout "Missing #{n_missing_tests} tests." if missing_tests?
  end
end

#runObject



45
46
47
48
49
50
51
52
# File 'lib/asautotest/test-runner.rb', line 45

def run
  whisper "Running tests via socket connection."
  with_server_running { run_test }
rescue TestMisbehaving
  shout "Terminating misbehaving test."
rescue TestMisbehavingFatally
  exit -1
end

#run_testObject



54
55
56
57
58
59
60
# File 'lib/asautotest/test-runner.rb', line 54

def run_test
  with_flash_running do
    accept_connection
    shake_hands
    talk_to_test
  end
end

#shake_handsObject



131
132
133
134
135
# File 'lib/asautotest/test-runner.rb', line 131

def shake_hands
  Timeout.timeout(1) { parse_greeting(read_greeting) }
rescue Timeout::Error
  misbehavior! "Handshake took too long."
end

#start_flashObject



93
94
95
# File 'lib/asautotest/test-runner.rb', line 93

def start_flash
  @flash_pid = fork { exec FLASHPLAYER, @binary_name }
end

#start_serverObject



73
74
75
76
# File 'lib/asautotest/test-runner.rb', line 73

def start_server
  @server = TCPServer.new(@port)
  @server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
end

#stop_flashObject



97
98
99
100
# File 'lib/asautotest/test-runner.rb', line 97

def stop_flash
  Process.kill("TERM", @flash_pid)
  Process.wait(@flash_pid)
end

#stop_serverObject



78
79
80
# File 'lib/asautotest/test-runner.rb', line 78

def stop_server
  @server.close
end

#suitesObject



227
228
229
# File 'lib/asautotest/test-runner.rb', line 227

def suites
  @suites.values
end

#talk_patiently_to_testObject



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/asautotest/test-runner.rb', line 189

def talk_patiently_to_test
  catch(:done) do
    loop do
      line = @socket.readline.chomp
      case line
      when /^plan (\d+)$/
        if @n_planned_tests != nil
          misbehavior! "Got another plan: #{line.inspect}"
        elsif n_completed_tests > 0
          misbehavior! "Got plan too late: #{line.inspect}"
        else
          @n_planned_tests = $1.to_i
          whisper "Planning to run #{@n_planned_tests} tests."
        end
      when "done"
        throw :done
      when /^xml-result: (.*)/
        begin
          result = Result.parse_xml($1)
          get_suite(result.suite_name) << result
        rescue Result::ParseError
          misbehavior! "Could not interpret XML result: #$1"
        end
      else
        puts ">> #{line.inspect}"
      end
    end
  end
end

#talk_to_testObject



157
158
159
160
161
162
163
# File 'lib/asautotest/test-runner.rb', line 157

def talk_to_test
  @test_stopwatch = Stopwatch.new
  Timeout.timeout(10) { talk_patiently_to_test }
  report_results
rescue Timeout::Error
  misbehavior! "Test run taking too long; aborting."
end

#test_count_reportObject



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/asautotest/test-runner.rb', line 175

def test_count_report
  build_string do |result|
    result << "Ran #{n_completed_tests} tests"

    if new_tests?
      result << " (#{n_new_tests} new)"
    elsif missing_tests?
      result << " (too few)"
    end

    result << " in ~#@test_stopwatch seconds."
  end
end

#with_flash_runningObject




84
85
86
87
88
89
90
91
# File 'lib/asautotest/test-runner.rb', line 84

def with_flash_running
  start_flash
  begin
    yield
  ensure
    stop_flash
  end
end

#with_server_runningObject




64
65
66
67
68
69
70
71
# File 'lib/asautotest/test-runner.rb', line 64

def with_server_running
  start_server
  begin
    yield
  ensure
    stop_server
  end
end