turbot-runner 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module TurbotRunner
2
- VERSION = '0.0.20'
2
+ VERSION = '0.0.21'
3
3
  end
data/lib/turbot_runner.rb CHANGED
@@ -11,6 +11,7 @@ module TurbotRunner
11
11
  class BaseRunner
12
12
 
13
13
  attr_reader :wait_thread
14
+ attr_reader :error
14
15
 
15
16
  def initialize(bot_directory)
16
17
  @bot_directory = bot_directory
@@ -28,7 +29,6 @@ module TurbotRunner
28
29
  @status = :initialized
29
30
  @interrupted = false
30
31
  @schemas = {}
31
- # @seen_uids = Set.new
32
32
  end
33
33
 
34
34
  def run(opts={})
@@ -49,7 +49,18 @@ module TurbotRunner
49
49
  begin
50
50
  until @interrupted do
51
51
  line = scraper_runner.get_next_line
52
- break if line.nil?
52
+
53
+ if line.nil?
54
+ if scraper_runner.finished?
55
+ if scraper_runner.success?
56
+ break
57
+ else
58
+ scraper_runner.raise_if_failed!
59
+ end
60
+ else
61
+ next
62
+ end
63
+ end
53
64
 
54
65
  begin
55
66
  record = JSON.parse(line)
@@ -67,12 +78,29 @@ module TurbotRunner
67
78
  data_type1 = transformer['data_type']
68
79
 
69
80
  runner = transformer['runner']
81
+ runner.raise_if_failed!
82
+
70
83
  runner.send_line(line)
71
84
  line1 = runner.get_next_line
72
85
 
73
- # A transformer should output an empty line if it doesn't make
86
+ if line1.nil?
87
+ if runner.finished?
88
+ if runner.success?
89
+ break
90
+ else
91
+ runner.raise_if_failed!
92
+ end
93
+ else
94
+ next
95
+ end
96
+ end
97
+
98
+ # A transformer can output an empty line if it doesn't make
74
99
  # sense to transform a record.
75
- next if line1.strip.empty?
100
+ if line1.strip.empty?
101
+ puts
102
+ next
103
+ end
76
104
 
77
105
  begin
78
106
  record1 = JSON.parse(line1)
@@ -106,6 +134,7 @@ module TurbotRunner
106
134
  handle_interrupted_run
107
135
  else
108
136
  @status = :failed
137
+ @error = e
109
138
  handle_failed_run
110
139
  end
111
140
  end
@@ -227,24 +256,48 @@ module TurbotRunner
227
256
  end
228
257
 
229
258
  class CommandRunner
259
+
260
+ def to_s
261
+ "CommandRunner #{@command}, pid #{@wait_thread.pid} (#{@wait_thread.status})"
262
+ end
263
+
230
264
  def initialize(command, opts={})
231
265
  @command = command
232
266
  @timeout = opts[:timeout] ||= 3600
233
- @stdin, @stdout, @wait_thread = Open3.popen2(command)
267
+ @stdin, @stdout, @stderr, @wait_thread = Open3.popen3(command)
234
268
  end
235
269
 
236
270
  def get_next_line
237
271
  begin
238
272
  Timeout::timeout(@timeout) { @stdout.gets }
239
273
  rescue Timeout::Error
240
- STDOUT.puts("#{@command} produced no output for #{@timeout} seconds")
241
- raise ScriptError
274
+ raise TurbotRunner::ScriptError.new("#{@command} produced no output for #{@timeout} seconds")
242
275
  rescue EOFError
243
- raise ScriptError unless @wait_thread.value.success?
276
+ raise_if_failed!
244
277
  return nil
245
278
  end
246
279
  end
247
280
 
281
+ def success?
282
+ if finished?
283
+ @wait_thread.value.success?
284
+ end
285
+ end
286
+
287
+ def failed?
288
+ if finished?
289
+ !@wait_thread.value.success?
290
+ end
291
+ end
292
+
293
+ def raise_if_failed!
294
+ raise TurbotRunner::ScriptError.new(@stderr.read()) if failed?
295
+ end
296
+
297
+ def finished?
298
+ !@wait_thread.status
299
+ end
300
+
248
301
  def send_line(line)
249
302
  @stdin.puts(line)
250
303
  end
@@ -1,6 +1,6 @@
1
1
  require 'json'
2
-
3
2
  STDIN.each_line do |line|
3
+
4
4
  raw_record = JSON.parse(line)
5
5
 
6
6
  transformed_record = {
@@ -0,0 +1,8 @@
1
+ {
2
+ "bot_id": "dummy-bot",
3
+ "data_type": "hello",
4
+ "description": "This is a dummy bot",
5
+ "identifying_fields": ["number"],
6
+ "files": ["scraper.rb"],
7
+ "frequency": "monthly"
8
+ }
@@ -0,0 +1,4 @@
1
+ require 'json'
2
+
3
+ puts({h: 1}.to_json)
4
+ raise "oops"
@@ -0,0 +1,12 @@
1
+ require 'json'
2
+
3
+ STDIN.each_line do |line|
4
+ raw_record = JSON.parse(line)
5
+
6
+ transformed_record = {
7
+ :n => raw_record['n'],
8
+ :goodbye => raw_record['hello'].sub('hello', 'goodbye')
9
+ }
10
+
11
+ puts transformed_record.to_json
12
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "bot_id": "dummy-bot",
3
+ "data_type": "hello",
4
+ "description": "This is a dummy bot",
5
+ "identifying_fields": ["number"],
6
+ "files": ["scraper.rb"],
7
+ "transformers": [
8
+ {
9
+ "file": "transformer.rb",
10
+ "data_type": "goodbye",
11
+ "identifying_fields": [""]
12
+ }
13
+ ],
14
+ "frequency": "monthly"
15
+ }
@@ -0,0 +1,4 @@
1
+ require 'json'
2
+
3
+ puts({h: 1}.to_json)
4
+ raise "oops"
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+
3
+ STDIN.each_line do |line|
4
+ raw_record = JSON.parse(line)
5
+
6
+ transformed_record = {
7
+ :p => raw_record['n'],
8
+ }
9
+
10
+ puts transformed_record.to_json
11
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "bot_id": "dummy-bot",
3
+ "data_type": "hello",
4
+ "description": "This is a dummy bot",
5
+ "identifying_fields": ["number"],
6
+ "files": ["scraper.rb"],
7
+ "transformers": [
8
+ {
9
+ "file": "transformer.rb",
10
+ "data_type": "goodbye",
11
+ "identifying_fields": [""]
12
+ }
13
+ ],
14
+ "frequency": "monthly"
15
+ }
@@ -0,0 +1,5 @@
1
+ require 'json'
2
+
3
+ 3.times do |n|
4
+ puts({h: n}.to_json)
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'json'
2
+
3
+ STDIN.each_line do |line|
4
+ raise "oops"
5
+ end
@@ -11,6 +11,19 @@ class SpecRunner < TurbotRunner::BaseRunner
11
11
  end
12
12
  end
13
13
 
14
+ class BrokenRunner < TurbotRunner::BaseRunner
15
+ def validate(record, data_type)
16
+ []
17
+ end
18
+
19
+ def handle_valid_record(*args)
20
+ end
21
+
22
+ def handle_failed_run
23
+ end
24
+ end
25
+
26
+
14
27
  describe TurbotRunner::BaseRunner do
15
28
  it 'can run a ruby bot' do
16
29
  runner = SpecRunner.new('spec/dummy-bot-ruby')
@@ -39,4 +52,40 @@ describe TurbotRunner::BaseRunner do
39
52
  expect(runner).to receive(:handle_successful_run)
40
53
  runner.run
41
54
  end
55
+
56
+ describe "broken bots" do
57
+ describe "failing bot without transformer" do
58
+ it 'should call handle_failed_run' do
59
+ runner = BrokenRunner.new('spec/dummy-broken-bot-ruby')
60
+ expect(runner).to receive(:handle_valid_record)
61
+ expect(runner).to receive(:handle_failed_run)
62
+ runner.run
63
+ end
64
+
65
+ it 'should set `error` attribute of runner with exception message' do
66
+ runner = BrokenRunner.new('spec/dummy-broken-bot-ruby')
67
+ runner.run
68
+ expect(runner.error.to_s).to match(/oops/)
69
+ end
70
+ end
71
+
72
+ describe "failing bot with successful transformer" do
73
+ it 'should call handle_failed_run' do
74
+ runner = BrokenRunner.new('spec/dummy-broken-bot-ruby-2')
75
+ expect(runner).to receive(:handle_valid_record) # first record
76
+ expect(runner).to receive(:handle_valid_record) # first transform
77
+ expect(runner).to receive(:handle_failed_run)
78
+ runner.run
79
+ end
80
+ end
81
+
82
+ describe "sucessful bot with failing transformer" do
83
+ it 'should call handle_failed_run' do
84
+ runner = BrokenRunner.new('spec/dummy-broken-bot-ruby-3')
85
+ expect(runner).to receive(:handle_valid_record) # the untransformed one
86
+ expect(runner).to receive(:handle_failed_run) # the transformer breaks immediately
87
+ runner.run
88
+ end
89
+ end
90
+ end
42
91
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbot-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.21
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-22 00:00:00.000000000 Z
12
+ date: 2014-07-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json-schema
@@ -43,6 +43,15 @@ files:
43
43
  - spec/dummy-bot-ruby/manifest.json
44
44
  - spec/dummy-bot-ruby/scraper.rb
45
45
  - spec/dummy-bot-ruby/transformer.rb
46
+ - spec/dummy-broken-bot-ruby-2/manifest.json
47
+ - spec/dummy-broken-bot-ruby-2/scraper.rb
48
+ - spec/dummy-broken-bot-ruby-2/transformer.rb
49
+ - spec/dummy-broken-bot-ruby-3/manifest.json
50
+ - spec/dummy-broken-bot-ruby-3/scraper.rb
51
+ - spec/dummy-broken-bot-ruby-3/transformer.rb
52
+ - spec/dummy-broken-bot-ruby/manifest.json
53
+ - spec/dummy-broken-bot-ruby/scraper.rb
54
+ - spec/dummy-broken-bot-ruby/transformer.rb
46
55
  - spec/turbot_runner_spec.rb
47
56
  - schema/schemas/company-schema.json
48
57
  - schema/schemas/financial-payment-schema.json