bricolage-streamingload 0.14.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,31 +0,0 @@
1
- require 'test/unit'
2
- require 'bricolage/streamingload/dispatchermessage'
3
-
4
- module Bricolage::StreamingLoad
5
-
6
- class TestDispatcherMessage < Test::Unit::TestCase
7
-
8
- def new_s3event(message_id: nil, receipt_handle: nil, name: nil, time: nil, source: nil, region: nil, bucket: nil, key: nil, size: nil)
9
- S3ObjectDispatcherMessage.new(
10
- message_id: message_id,
11
- receipt_handle: receipt_handle,
12
- name: name,
13
- time: time,
14
- source: source,
15
- region: region,
16
- bucket: bucket,
17
- key: key,
18
- size: size
19
- )
20
- end
21
-
22
- test "#created?" do
23
- e = new_s3event(name: "ObjectCreated:Put")
24
- assert_true e.created_event?
25
- e = new_s3event(name: "ObjectCreated:Copy")
26
- assert_false e.created_event?
27
- end
28
-
29
- end
30
-
31
- end
@@ -1,590 +0,0 @@
1
- require 'test/unit'
2
- require 'bricolage/streamingload/job'
3
- require 'bricolage/context'
4
- require 'bricolage/logger'
5
-
6
- module Bricolage
7
-
8
- # FIXME: patch
9
- class NullLogger
10
- def log(*args) end
11
- def add(*args) end
12
- end
13
-
14
- module StreamingLoad
15
-
16
- class TestJob < Test::Unit::TestCase
17
-
18
- test "execute_task" do
19
- setup_context {|db|
20
- db.insert_into 'strload_tables', [1, 'testschema.desttable', 'testschema', 'desttable', 100, 1800, false]
21
- db.insert_into 'strload_tasks', [1, 'streaming_load_v3', 1, current_timestamp]
22
- db.insert_into 'strload_task_objects', [1, 1], [1, 2]
23
- db.insert_into 'strload_objects',
24
- [1, 's3://data-bucket/testschema.desttable/0001.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp],
25
- [2, 's3://data-bucket/testschema.desttable/0002.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp]
26
-
27
- job = new_job(task_id: 1, force: false)
28
- job.execute_task
29
-
30
- assert_equal [
31
- "begin transaction;",
32
- "copy testschema.desttable from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
33
- "insert into strload_load_logs (task_id, job_id, finish_time) values (1, #{job.job_id}, current_timestamp)",
34
- "commit;"
35
- ], job.data_ds.sql_list
36
-
37
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
38
- assert_equal 1, job_row['task_id'].to_i
39
- assert_equal job.process_id, job_row['process_id']
40
- assert_equal 'success', job_row['status']
41
- }
42
- end
43
-
44
- test "execute_task (with work table)" do
45
- setup_context {|db|
46
- db.insert_into 'strload_tables', [1, 'testschema.with_work_table', 'testschema', 'with_work_table', 100, 1800, false]
47
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
48
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
49
- db.insert_into 'strload_objects',
50
- [1001, 's3://data-bucket/testschema.with_work_table/0001.json.gz', 1024, 'testschema.with_work_table', 'mmmm', current_timestamp, current_timestamp],
51
- [1002, 's3://data-bucket/testschema.with_work_table/0002.json.gz', 1024, 'testschema.with_work_table', 'mmmm', current_timestamp, current_timestamp]
52
-
53
- job = new_job(task_id: 11, force: false)
54
- job.execute_task
55
-
56
- assert_equal [
57
- "begin transaction;",
58
- "delete from testschema.with_work_table_wk",
59
- "copy testschema.with_work_table_wk from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
60
- "insert into testschema.with_work_table select * from testschema.with_work_table_wk;\n",
61
- "insert into strload_load_logs (task_id, job_id, finish_time) values (11, #{job.job_id}, current_timestamp)",
62
- "truncate testschema.with_work_table_wk;"
63
- ], job.data_ds.sql_list
64
-
65
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
66
- assert_equal 11, job_row['task_id'].to_i
67
- assert_equal job.process_id, job_row['process_id']
68
- assert_equal 'success', job_row['status']
69
- }
70
- end
71
-
72
- test "execute_task (disabled)" do
73
- setup_context {|db|
74
- db.insert_into 'strload_tables', [1, 'testschema.desttable', 'testschema', 'desttable', 100, 1800, true]
75
- db.insert_into 'strload_tasks', [1, 'streaming_load_v3', 1, current_timestamp]
76
-
77
- job = new_job(task_id: 1, force: false)
78
- assert_raise(JobDefered) {
79
- job.execute_task
80
- }
81
- count = db.query_value("select count(*) from strload_jobs")
82
- assert_equal 0, count.to_i
83
- }
84
- end
85
-
86
- test "execute_task (duplicated)" do
87
- setup_context {|db|
88
- db.insert_into 'strload_tables', [1, 'testschema.desttable', 'testschema', 'desttable', 100, 1800, false]
89
- db.insert_into 'strload_tasks', [1, 'streaming_load_v3', 1, current_timestamp]
90
- db.insert_into 'strload_jobs',
91
- [1, 1, 'localhost-1234', 'failure', current_timestamp, current_timestamp, ''],
92
- [2, 1, 'localhost-1234', 'success', current_timestamp, current_timestamp, ''],
93
- [3, 1, 'localhost-1234', 'duplicated', current_timestamp, current_timestamp, '']
94
-
95
- job = new_job(task_id: 1, force: false)
96
- assert_raise(JobDuplicated) {
97
- job.execute_task
98
- }
99
- }
100
- end
101
-
102
- test "execute_task (duplicated but forced)" do
103
- setup_context {|db|
104
- db.insert_into 'strload_tables', [1, 'testschema.desttable', 'testschema', 'desttable', 100, 1800, false]
105
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
106
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
107
- db.insert_into 'strload_objects',
108
- [1001, 's3://data-bucket/testschema.desttable/0001.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp],
109
- [1002, 's3://data-bucket/testschema.desttable/0002.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp]
110
-
111
- job = new_job(task_id: 11, force: true)
112
- job.execute_task
113
-
114
- assert_equal [
115
- "begin transaction;",
116
- "copy testschema.desttable from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
117
- "insert into strload_load_logs (task_id, job_id, finish_time) values (11, #{job.job_id}, current_timestamp)",
118
- "commit;"
119
- ], job.data_ds.sql_list
120
-
121
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
122
- assert_equal 11, job_row['task_id'].to_i
123
- assert_equal job.process_id, job_row['process_id']
124
- assert_equal 'success', job_row['status']
125
- assert(/forced/ =~ job_row['message'])
126
- }
127
- end
128
-
129
- test "execute_task (load fails / first time)" do
130
- setup_context {|db|
131
- db.insert_into 'strload_tables', [1, 'testschema.sql_fails', 'testschema', 'sql_fails', 100, 1800, false]
132
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
133
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
134
- db.insert_into 'strload_objects',
135
- [1001, 's3://data-bucket/testschema.desttable/0001.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp],
136
- [1002, 's3://data-bucket/testschema.desttable/0002.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp]
137
-
138
- job = new_job(task_id: 11, force: false)
139
- assert_raise(JobFailure) {
140
- job.execute_task
141
- }
142
- assert_equal [
143
- "begin transaction;",
144
- "copy testschema.sql_fails from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
145
- "abort;"
146
- ], job.data_ds.sql_list
147
-
148
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
149
- assert_equal 11, job_row['task_id'].to_i
150
- assert_equal job.process_id, job_row['process_id']
151
- assert_equal 'failure', job_row['status']
152
- }
153
- end
154
-
155
- test "execute_task (load fails / nth time)" do
156
- setup_context {|db|
157
- db.insert_into 'strload_tables', [1, 'testschema.sql_fails', 'testschema', 'sql_fails', 100, 1800, false]
158
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
159
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
160
- db.insert_into 'strload_objects',
161
- [1001, 's3://data-bucket/testschema.sql_fails/0001.json.gz', 1024, 'testschema.sql_fails', 'mmmm', current_timestamp, current_timestamp],
162
- [1002, 's3://data-bucket/testschema.sql_fails/0002.json.gz', 1024, 'testschema.sql_fails', 'mmmm', current_timestamp, current_timestamp]
163
- db.insert_into 'strload_jobs',
164
- [101, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'query failed'],
165
- [102, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'query failed']
166
-
167
- job = new_job(task_id: 11, force: false)
168
- assert_raise(JobFailure) {
169
- job.execute_task
170
- }
171
- assert_equal [
172
- "begin transaction;",
173
- "copy testschema.sql_fails from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
174
- "abort;"
175
- ], job.data_ds.sql_list
176
-
177
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
178
- assert_equal 11, job_row['task_id'].to_i
179
- assert_equal job.process_id, job_row['process_id']
180
- assert_equal 'failure', job_row['status']
181
- assert(/retry\#2/ =~ job_row['message'])
182
- }
183
- end
184
-
185
- test "execute_task (too many retry)" do
186
- setup_context {|db|
187
- db.insert_into 'strload_tables', [1, 'testschema.sql_fails', 'testschema', 'sql_fails', 100, 1800, false]
188
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
189
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
190
- db.insert_into 'strload_objects',
191
- [1001, 's3://data-bucket/testschema.sql_fails/0001.json.gz', 1024, 'testschema.sql_fails', 'mmmm', current_timestamp, current_timestamp],
192
- [1002, 's3://data-bucket/testschema.sql_fails/0002.json.gz', 1024, 'testschema.sql_fails', 'mmmm', current_timestamp, current_timestamp]
193
- db.insert_into 'strload_jobs',
194
- [101, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'query failed'],
195
- [102, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'retry#1 query failed'],
196
- [103, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'retry#2 query failed'],
197
- [104, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'retry#3 query failed'],
198
- [105, 11, 'localhost-1234', 'failure', current_timestamp, current_timestamp, 'retry#4 query failed']
199
-
200
- job = new_job(task_id: 11, force: false)
201
- assert_raise(JobCancelled) {
202
- job.execute_task
203
- }
204
- assert_equal [
205
- "begin transaction;",
206
- "copy testschema.sql_fails from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
207
- "abort;"
208
- ], job.data_ds.sql_list
209
-
210
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
211
- assert_equal 11, job_row['task_id'].to_i
212
- assert_equal job.process_id, job_row['process_id']
213
- assert_equal 'failure', job_row['status']
214
- assert(/retry\#5 FINAL/ =~ job_row['message'])
215
- }
216
- end
217
-
218
- test "execute_task (job error)" do
219
- setup_context {|db|
220
- db.insert_into 'strload_tables', [1, 'testschema.job_error', 'testschema', 'job_error', 100, 1800, false]
221
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
222
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
223
- db.insert_into 'strload_objects',
224
- [1001, 's3://data-bucket/testschema.job_error/0001.json.gz', 1024, 'testschema.job_error', 'mmmm', current_timestamp, current_timestamp],
225
- [1002, 's3://data-bucket/testschema.job_error/0002.json.gz', 1024, 'testschema.job_error', 'mmmm', current_timestamp, current_timestamp]
226
-
227
- job = new_job(task_id: 11, force: false)
228
- assert_raise(JobError) {
229
- job.execute_task
230
- }
231
- assert_equal [
232
- "begin transaction;",
233
- "copy testschema.job_error from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
234
- "abort;"
235
- ], job.data_ds.sql_list
236
-
237
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
238
- assert_equal 11, job_row['task_id'].to_i
239
- assert_equal job.process_id, job_row['process_id']
240
- assert_equal 'error', job_row['status']
241
- }
242
- end
243
-
244
- test "execute_task (unexpected error)" do
245
- setup_context {|db|
246
- db.insert_into 'strload_tables', [1, 'testschema.unexpected_error', 'testschema', 'unexpected_error', 100, 1800, false]
247
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
248
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
249
- db.insert_into 'strload_objects',
250
- [1001, 's3://data-bucket/testschema.unexpected_error/0001.json.gz', 1024, 'testschema.unexpected_error', 'mmmm', current_timestamp, current_timestamp],
251
- [1002, 's3://data-bucket/testschema.unexpected_error/0002.json.gz', 1024, 'testschema.unexpected_error', 'mmmm', current_timestamp, current_timestamp]
252
-
253
- job = new_job(task_id: 11, force: false)
254
- assert_raise(JobError) {
255
- job.execute_task
256
- }
257
- assert_equal [
258
- "begin transaction;",
259
- "copy testschema.unexpected_error from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
260
- "abort;"
261
- ], job.data_ds.sql_list
262
-
263
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
264
- assert_equal 11, job_row['task_id'].to_i
265
- assert_equal job.process_id, job_row['process_id']
266
- assert_equal 'error', job_row['status']
267
- }
268
- end
269
-
270
- test "execute_task (unknown status, really=success)" do
271
- setup_context {|db|
272
- db.insert_into 'strload_tables', [1, 'testschema.desttable', 'testschema', 'desttable', 100, 1800, false]
273
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
274
- db.insert_into 'strload_jobs',
275
- [101, 11, 'localhost-1234', 'unknown', current_timestamp, current_timestamp, 'data connection failed']
276
- @data_ds.provide_job_status 101, true
277
-
278
- job = new_job(task_id: 11, force: false)
279
- assert_raise(JobDuplicated) {
280
- job.execute_task
281
- }
282
-
283
- job_row = db.query_row("select * from strload_jobs where job_id = 101")
284
- assert_equal 'success', job_row['status']
285
- }
286
- end
287
-
288
- test "execute_task (unknown status, really=failure)" do
289
- setup_context {|db|
290
- db.insert_into 'strload_tables', [1, 'testschema.desttable', 'testschema', 'desttable', 100, 1800, false]
291
- db.insert_into 'strload_tasks', [11, 'streaming_load_v3', 1, current_timestamp]
292
- db.insert_into 'strload_task_objects', [11, 1001], [11, 1002]
293
- db.insert_into 'strload_objects',
294
- [1001, 's3://data-bucket/testschema.desttable/0001.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp],
295
- [1002, 's3://data-bucket/testschema.desttable/0002.json.gz', 1024, 'testschema.desttable', 'mmmm', current_timestamp, current_timestamp]
296
- db.insert_into 'strload_jobs',
297
- [101, 11, 'localhost-1234', 'unknown', current_timestamp, current_timestamp, 'data connection failed']
298
- @data_ds.provide_job_status 101, false
299
-
300
- job = new_job(task_id: 11, force: false)
301
- job.execute_task
302
-
303
- assert_equal [
304
- "begin transaction;",
305
- "copy testschema.desttable from '#{job.manifest.url}' credentials 'cccc' manifest statupdate false compupdate false json 'auto' gzip timeformat 'auto' dateformat 'auto' acceptanydate acceptinvchars ' ' truncatecolumns trimblanks ;",
306
- "insert into strload_load_logs (task_id, job_id, finish_time) values (11, #{job.job_id}, current_timestamp)",
307
- "commit;"
308
- ], job.data_ds.sql_list
309
-
310
- job_row = db.query_row("select * from strload_jobs where job_id = 101")
311
- assert_equal 'failure', job_row['status']
312
-
313
- job_row = db.query_row("select * from strload_jobs where job_id = #{job.job_id}")
314
- assert_equal 11, job_row['task_id'].to_i
315
- assert_equal job.process_id, job_row['process_id']
316
- assert_equal 'success', job_row['status']
317
- }
318
- end
319
-
320
- def setup_context(verbose: false)
321
- @ctx = Context.for_application('.', environment: 'test', logger: (verbose ? nil : NullLogger.new))
322
- @ctl_ds = @ctx.get_data_source('sql', 'dwhctl')
323
- @data_ds = @ctx.get_data_source('sql', 'db_data_mock')
324
- @ctl_ds.open {|conn|
325
- client = SQLClient.new(conn)
326
- clear_all_tables(client)
327
- yield client
328
- }
329
- end
330
-
331
- def new_job(task_id:, force:)
332
- Job.new(
333
- context: @ctx,
334
- ctl_ds: @ctl_ds,
335
- data_ds: @data_ds,
336
- logger: @ctx.logger,
337
- task_id: task_id,
338
- force: force
339
- )
340
- end
341
-
342
- # FIXME: database cleaner
343
- def clear_all_tables(client)
344
- client.truncate_tables %w[
345
- strload_tables
346
- strload_objects
347
- strload_task_objects
348
- strload_tasks
349
- strload_jobs
350
- ]
351
- end
352
-
353
- class SQLClient
354
- include SQLUtils
355
-
356
- def initialize(conn)
357
- @conn = conn
358
- end
359
-
360
- extend Forwardable
361
- def_delegators '@conn',
362
- :query,
363
- :query_value,
364
- :query_values,
365
- :query_row,
366
- :select,
367
- :update
368
-
369
- def insert_into(table, *records)
370
- sql = "insert into #{table}"
371
- sep = ' values '
372
- records.each do |rec|
373
- sql << sep; sep = ', '
374
- sql << format_values(rec)
375
- end
376
- @conn.update(sql)
377
- end
378
-
379
- def truncate_tables(tables)
380
- tables.each do |name|
381
- @conn.update("truncate #{name}")
382
- end
383
- end
384
-
385
- private
386
-
387
- def format_values(rec)
388
- '(' + rec.map {|val| format_value(val) }.join(', ') + ')'
389
- end
390
-
391
- def format_value(val)
392
- case val
393
- when nil then 'null'
394
- when true, false then val.to_s
395
- when Integer then val.to_s
396
- when SQLExpr then val.to_s
397
- when String then sql_string_literal(val)
398
- else
399
- raise ArgumentError, "unsupported value type: #{val.class}: #{val.inspect}"
400
- end
401
- end
402
-
403
- module DSL
404
- def null
405
- nil
406
- end
407
-
408
- def current_timestamp
409
- SQLExpr.new('current_timestamp')
410
- end
411
-
412
- def sql(expr)
413
- SQLExpr.new(expr)
414
- end
415
- end
416
-
417
- class SQLExpr
418
- def initialize(expr)
419
- @expr = expr
420
- end
421
-
422
- def to_s
423
- @expr
424
- end
425
- end
426
- end
427
-
428
- include SQLClient::DSL
429
-
430
- class PSQLDataSourceMock < DataSource
431
- declare_type 'psql_mock'
432
-
433
- def initialize(fail_pattern: nil, error_pattern: nil, exception_pattern: nil, **params)
434
- @sql_list = []
435
- @fail_pattern = fail_pattern ? Regexp.compile(fail_pattern) : nil
436
- @error_pattern = error_pattern ? Regexp.compile(error_pattern) : nil
437
- @exception_pattern = exception_pattern ? Regexp.compile(exception_pattern) : nil
438
- @job_status = {}
439
- end
440
-
441
- attr_reader :sql_list
442
-
443
- def open
444
- conn = Connection.new(self)
445
- if block_given?
446
- yield conn
447
- else
448
- conn
449
- end
450
- end
451
-
452
- def issue_sql(sql)
453
- logger.info "[mock] #{sql}"
454
- @sql_list.push sql
455
- if @fail_pattern and @fail_pattern =~ sql
456
- raise JobFailure, "query failed: #{sql}"
457
- end
458
- if @error_pattern and @error_pattern =~ sql
459
- raise JobError, "error"
460
- end
461
- if @exception_pattern and @exception_pattern =~ sql
462
- raise ArgumentError, "unexpected exception"
463
- end
464
- end
465
-
466
- def provide_job_status(job_id, succeeded)
467
- @job_status[job_id] = succeeded
468
- end
469
-
470
- def job_succeeded?(job_id)
471
- raise "job status unregistered: job_id=#{job_id}" unless @job_status.key?(job_id)
472
- @job_status[job_id]
473
- end
474
-
475
- class Connection
476
- def initialize(ds)
477
- @ds = ds
478
- end
479
-
480
- def query_value(sql)
481
- case sql
482
- when /\bstrload_load_logs where job_id = (\d+)/
483
- job_id = $1.to_i
484
- @ds.job_succeeded?(job_id) ? 1 : 0
485
- else
486
- raise "unknown query: #{sql}"
487
- end
488
- end
489
-
490
- def execute(sql)
491
- @ds.issue_sql sql
492
- end
493
-
494
- def transaction
495
- @ds.issue_sql "begin transaction;"
496
- txn = Transaction.new(@ds)
497
- yield txn
498
- rescue
499
- txn.abort unless txn.committed?
500
- raise
501
- ensure
502
- txn.commit unless txn.committed?
503
- end
504
- end
505
-
506
- class Transaction
507
- def initialize(ds)
508
- @ds = ds
509
- @commit = false
510
- end
511
-
512
- def committed?
513
- @commit
514
- end
515
-
516
- def commit
517
- @ds.issue_sql "commit;"
518
- @commit = true
519
- end
520
-
521
- def abort
522
- @ds.issue_sql "abort;"
523
- @commit = true
524
- end
525
-
526
- def truncate_and_commit(table)
527
- @ds.issue_sql "truncate #{table};"
528
- @commit = true
529
- end
530
- end
531
- end
532
-
533
- class S3DataSourceMock < DataSource
534
- declare_type 's3_mock'
535
-
536
- def initialize(**params)
537
- end
538
-
539
- def credential_string
540
- 'cccc'
541
- end
542
-
543
- def url(name)
544
- "s3://bucket/prefix/#{name}"
545
- end
546
-
547
- def object(name)
548
- ObjectMock.new(url(name), logger)
549
- end
550
-
551
- class ObjectMock
552
- def initialize(url, logger)
553
- @url = url
554
- @logger = logger
555
- end
556
-
557
- def put(body:)
558
- @logger.info "[mock] S3 PUT #{@url} content=#{body[0,20].inspect}..."
559
- end
560
-
561
- def delete
562
- @logger.info "[mock] S3 DELETE #{@url}"
563
- end
564
- end
565
- end
566
-
567
- test "TaskInfo#failure_count" do
568
- test_data = [
569
- [%w[], 0],
570
- [%w[success], 0],
571
- [%w[failure], 1],
572
- [%w[error], 1],
573
- [%w[failure failure], 2],
574
- [%w[failure error], 2],
575
- [%w[failure success], 0],
576
- [%w[success success], 0],
577
- [%w[failure success failure], 1],
578
- [%w[failure success failure success failure failure], 2]
579
- ]
580
- c = Job::ControlConnection
581
- test_data.each do |status_list, expected_count|
582
- task = c::TaskInfo.new(nil,nil,nil,nil,nil,nil, status_list.map {|st| c::JobInfo.new(nil, st) })
583
- assert_equal expected_count, task.failure_count
584
- end
585
- end
586
-
587
- end # class TestJob
588
-
589
- end # module StreamingLoad
590
- end # module Bricolage