bricolage 5.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +4 -0
  3. data/bin/bricolage +6 -0
  4. data/bin/bricolage-jobnet +6 -0
  5. data/jobclass/create.rb +21 -0
  6. data/jobclass/exec.rb +17 -0
  7. data/jobclass/insert-delta.rb +31 -0
  8. data/jobclass/insert.rb +33 -0
  9. data/jobclass/load.rb +39 -0
  10. data/jobclass/my-export.rb +40 -0
  11. data/jobclass/my-migrate.rb +103 -0
  12. data/jobclass/noop.rb +13 -0
  13. data/jobclass/rebuild-drop.rb +37 -0
  14. data/jobclass/rebuild-rename.rb +49 -0
  15. data/jobclass/s3-put.rb +19 -0
  16. data/jobclass/sql.rb +29 -0
  17. data/jobclass/td-delete.rb +20 -0
  18. data/jobclass/td-export.rb +30 -0
  19. data/jobclass/unload.rb +30 -0
  20. data/jobclass/wait-file.rb +48 -0
  21. data/lib/bricolage/application.rb +260 -0
  22. data/lib/bricolage/commandutils.rb +52 -0
  23. data/lib/bricolage/configloader.rb +126 -0
  24. data/lib/bricolage/context.rb +108 -0
  25. data/lib/bricolage/datasource.rb +144 -0
  26. data/lib/bricolage/eventhandlers.rb +47 -0
  27. data/lib/bricolage/exception.rb +47 -0
  28. data/lib/bricolage/filedatasource.rb +42 -0
  29. data/lib/bricolage/filesystem.rb +165 -0
  30. data/lib/bricolage/genericdatasource.rb +37 -0
  31. data/lib/bricolage/job.rb +212 -0
  32. data/lib/bricolage/jobclass.rb +98 -0
  33. data/lib/bricolage/jobfile.rb +100 -0
  34. data/lib/bricolage/jobflow.rb +389 -0
  35. data/lib/bricolage/jobnetrunner.rb +264 -0
  36. data/lib/bricolage/jobresult.rb +74 -0
  37. data/lib/bricolage/logger.rb +52 -0
  38. data/lib/bricolage/mysqldatasource.rb +223 -0
  39. data/lib/bricolage/parameters.rb +653 -0
  40. data/lib/bricolage/postgresconnection.rb +78 -0
  41. data/lib/bricolage/psqldatasource.rb +449 -0
  42. data/lib/bricolage/resource.rb +68 -0
  43. data/lib/bricolage/rubyjobclass.rb +42 -0
  44. data/lib/bricolage/s3datasource.rb +144 -0
  45. data/lib/bricolage/script.rb +120 -0
  46. data/lib/bricolage/sqlstatement.rb +351 -0
  47. data/lib/bricolage/taskqueue.rb +156 -0
  48. data/lib/bricolage/tddatasource.rb +116 -0
  49. data/lib/bricolage/variables.rb +208 -0
  50. data/lib/bricolage/version.rb +4 -0
  51. data/lib/bricolage.rb +8 -0
  52. data/libexec/sqldump +9 -0
  53. data/libexec/sqldump.Darwin +0 -0
  54. data/libexec/sqldump.Linux +0 -0
  55. data/test/all.rb +3 -0
  56. data/test/home/config/development/database.yml +57 -0
  57. data/test/home/config/development/password.yml +2 -0
  58. data/test/home/subsys/separated.job +1 -0
  59. data/test/home/subsys/separated.sql +1 -0
  60. data/test/home/subsys/unified.jobnet +1 -0
  61. data/test/home/subsys/unified.sql.job +5 -0
  62. data/test/test_filesystem.rb +19 -0
  63. data/test/test_parameters.rb +401 -0
  64. data/test/test_variables.rb +114 -0
  65. metadata +192 -0
@@ -0,0 +1,401 @@
1
+ require 'test/unit'
2
+ require 'bricolage/parameters'
3
+ require 'optparse'
4
+ require 'pp'
5
+
6
+ module Bricolage
7
+ class TestParameters < Test::Unit::TestCase
8
+ def apply_values(decls, values)
9
+ parser = Parameters::DirectValueHandler.new(decls)
10
+ parser.parse(values)
11
+ end
12
+
13
+ def apply_options(decls, argv)
14
+ parser = Parameters::CommandLineOptionHandler.new(decls)
15
+ opts = OptionParser.new
16
+ parser.define_options(opts)
17
+ opts.parse!(argv)
18
+ parser.values
19
+ end
20
+
21
+ def wrap_decl(decl)
22
+ Parameters::Declarations.new.tap {|params|
23
+ params.add decl
24
+ }
25
+ end
26
+
27
+ default_context = nil
28
+ default_variables = ResolvedVariables.new
29
+
30
+ # StringParam (8)
31
+
32
+ test "StringParam (*.job)" do
33
+ decls = wrap_decl StringParam.new('options', 'OPTIONS', 'Loader options.', optional: true)
34
+ pvals = apply_values(decls, {'options' => 'gzip, maxerror=3'})
35
+ params = pvals.resolve(default_context, default_variables)
36
+ assert_equal 'gzip, maxerror=3', params['options']
37
+ assert_false params.variables.bound?('options')
38
+ end
39
+
40
+ test "StringParam (--opt)" do
41
+ decls = wrap_decl StringParam.new('options', 'OPTIONS', 'Loader options.', optional: true)
42
+ pvals = apply_options(decls, ['--options=gzip, maxerror=3'])
43
+ params = pvals.resolve(default_context, default_variables)
44
+ assert_equal 'gzip, maxerror=3', params['options']
45
+ assert_false params.variables.bound?('options')
46
+ end
47
+
48
+ test "StringParam (default value)" do
49
+ decls = wrap_decl StringParam.new('options', 'OPTIONS', 'Loader options.', optional: true)
50
+ pvals = apply_values(decls, {})
51
+ params = pvals.resolve(default_context, default_variables)
52
+ assert_nil params['options']
53
+ end
54
+
55
+ test "StringParam (missing value)" do
56
+ decls = wrap_decl StringParam.new('delete-cond', 'SQL_EXPR', 'DELETE condition.')
57
+ pvals = apply_values(decls, {})
58
+ assert_raise(ParameterError) {
59
+ pvals.resolve(default_context, default_variables)
60
+ }
61
+ end
62
+
63
+ # BoolParam (0)
64
+
65
+ # OptionalBoolParam (41)
66
+
67
+ test "OptionalBoolParam (*.job)" do
68
+ decls = wrap_decl OptionalBoolParam.new('vacuum-sort', 'VACUUM SORT table after SQL is executed.')
69
+ pvals = apply_values(decls, {'vacuum-sort' => true})
70
+ params = pvals.resolve(default_context, default_variables)
71
+ assert_true params['vacuum-sort']
72
+ assert_false params.variables.bound?('vacuum_sort')
73
+ end
74
+
75
+ test "OptionalBoolParam (--opt)" do
76
+ decls = wrap_decl OptionalBoolParam.new('vacuum-sort', 'VACUUM SORT table after SQL is executed.', publish: true)
77
+ pvals = apply_options(decls, ['--vacuum-sort'])
78
+ params = pvals.resolve(default_context, default_variables)
79
+ assert_true params['vacuum-sort']
80
+ assert_equal 'true', params.variables['vacuum_sort']
81
+ end
82
+
83
+ test "OptionalBoolParam (default value #1)" do
84
+ decls = wrap_decl OptionalBoolParam.new('vacuum', 'VACUUM table after SQL is executed.')
85
+ pvals = apply_values(decls, {})
86
+ params = pvals.resolve(default_context, default_variables)
87
+ assert_false params['vacuum']
88
+ assert_false params.variables.bound?('vacuum')
89
+ end
90
+
91
+ test "OptionalBoolParam (default value #2)" do
92
+ decls = wrap_decl OptionalBoolParam.new('gzip', 'If true, compresses target file by gzip.', default: true)
93
+ pvals = apply_values(decls, {})
94
+ params = pvals.resolve(default_context, default_variables)
95
+ assert_true params['gzip']
96
+ assert_false params.variables.bound?('gzip')
97
+ end
98
+
99
+ # DateParam (2)
100
+
101
+ test "DateParam (*.job)" do
102
+ decls = wrap_decl DateParam.new('to', 'DATE', 'End date of logs to delete (%Y-%m-%d).')
103
+ pvals = apply_values(decls, {'to' => '2014-01-23'})
104
+ params = pvals.resolve(default_context, default_variables)
105
+ assert_equal Date.new(2014, 1, 23), params['to']
106
+ assert_false params.variables.bound?('to')
107
+ end
108
+
109
+ test "DateParam (--opt)" do
110
+ decls = wrap_decl DateParam.new('to', 'DATE', 'End date of logs to delete (%Y-%m-%d).', publish: true)
111
+ pvals = apply_options(decls, ['--to=2014-01-23'])
112
+ params = pvals.resolve(default_context, default_variables)
113
+ assert_equal Date.new(2014, 1, 23), params['to']
114
+ assert_equal '2014-01-23', params.variables['to']
115
+ end
116
+
117
+ test "DateParam (default value)" do
118
+ decls = wrap_decl DateParam.new('to', 'DATE', 'End date of logs to delete (%Y-%m-%d).', optional: true)
119
+ pvals = apply_values(decls, {})
120
+ params = pvals.resolve(default_context, default_variables)
121
+ assert_nil params['to']
122
+ assert_false params.variables.bound?('to')
123
+ end
124
+
125
+ # EnumParam (4)
126
+
127
+ test "EnumParam (*.job)" do
128
+ decls = wrap_decl EnumParam.new('format', %w(tsv json), 'Data file format.', default: 'tsv')
129
+ pvals = apply_values(decls, {'format' => 'json'})
130
+ params = pvals.resolve(default_context, default_variables)
131
+ assert_equal 'json', params['format']
132
+ assert_false params.variables.bound?('format')
133
+ end
134
+
135
+ test "EnumParam (--opt)" do
136
+ decls = wrap_decl EnumParam.new('format', %w(tsv json), 'Data file format.', default: nil, publish: true)
137
+ pvals = apply_options(decls, ['--format=tsv'])
138
+ params = pvals.resolve(default_context, default_variables)
139
+ assert_equal 'tsv', params['format']
140
+ assert_equal 'tsv', params.variables['format']
141
+ end
142
+
143
+ test "EnumParam (default value)" do
144
+ decls = wrap_decl EnumParam.new('format', %w(tsv json), 'Data file format.', default: 'tsv')
145
+ pvals = apply_values(decls, {})
146
+ params = pvals.resolve(default_context, default_variables)
147
+ assert_equal 'tsv', params['format']
148
+ end
149
+
150
+ # DataSourceParam (17)
151
+
152
+ class DummyContext_ds
153
+ def initialize(kind, name, result)
154
+ @kind = kind
155
+ @name = name
156
+ @result = result
157
+ end
158
+
159
+ def get_data_source(kind, name)
160
+ if kind == @kind and name == @name
161
+ @result
162
+ else
163
+ raise ParameterError, "wrong ds argument: #{kind}, #{name}"
164
+ end
165
+ end
166
+ end
167
+
168
+ DummyDataSource = Struct.new(:name)
169
+ app_ds = DummyDataSource.new('app')
170
+ sql_ds = DummyDataSource.new('sql')
171
+
172
+ test "DataSourceParam (*.job)" do
173
+ decls = wrap_decl DataSourceParam.new('sql')
174
+ pvals = apply_values(decls, {'data-source' => 'app'})
175
+ ctx = DummyContext_ds.new('sql', app_ds.name, app_ds)
176
+ params = pvals.resolve(ctx, default_variables)
177
+ assert_equal app_ds, params['data-source']
178
+ assert_false params.variables.bound?('data-source')
179
+ end
180
+
181
+ test "DataSourceParam (--opt)" do
182
+ decls = wrap_decl DataSourceParam.new('sql')
183
+ pvals = apply_options(decls, ['--data-source=app'])
184
+ ctx = DummyContext_ds.new('sql', app_ds.name, app_ds)
185
+ params = pvals.resolve(ctx, default_variables)
186
+ assert_equal app_ds, params['data-source']
187
+ assert_false params.variables.bound?('data-source')
188
+ end
189
+
190
+ test "DataSourceParam (default value)" do
191
+ decls = wrap_decl DataSourceParam.new('sql')
192
+ pvals = apply_values(decls, {})
193
+ ctx = DummyContext_ds.new('sql', nil, sql_ds)
194
+ params = pvals.resolve(ctx, default_variables)
195
+ assert_equal sql_ds, params['data-source']
196
+ assert_false params.variables.bound?('data-source')
197
+ end
198
+
199
+ # SQLFileParam (14)
200
+
201
+ DummyContext_sqlfile = Struct.new(:name, :ext, :result)
202
+ class DummyContext_sqlfile
203
+ def parameter_file(_name, _ext)
204
+ raise ParameterError, "bad argument: #{_name}, #{_ext}" unless [name, ext] == [_name, _ext]
205
+ result
206
+ end
207
+ end
208
+
209
+ dummy_sql_resource = StringResource.new("select * from t;")
210
+ dummy_sql_file = SQLStatement.new(dummy_sql_resource)
211
+
212
+ test "SQLFileParam (*.job)" do
213
+ decls = wrap_decl SQLFileParam.new
214
+ pvals = apply_values(decls, {'sql-file' => 'some_path.sql'})
215
+ ctx = DummyContext_sqlfile.new('some_path.sql', 'sql', dummy_sql_resource)
216
+ params = pvals.resolve(ctx, default_variables)
217
+ assert_equal dummy_sql_file, params['sql-file']
218
+ assert_false params.variables.bound?('sql_file')
219
+ end
220
+
221
+ test "SQLFileParam (--opt)" do
222
+ decls = wrap_decl SQLFileParam.new
223
+ pvals = apply_options(decls, ['--sql-file=some_path.sql'])
224
+ ctx = DummyContext_sqlfile.new('some_path.sql', 'sql', dummy_sql_resource)
225
+ params = pvals.resolve(ctx, default_variables)
226
+ assert_equal dummy_sql_file, params['sql-file']
227
+ assert_false params.variables.bound?('sql_file')
228
+ end
229
+
230
+ test "SQLFileParam (default value)" do
231
+ decls = wrap_decl SQLFileParam.new(optional: true)
232
+ pvals = apply_values(decls, {})
233
+ params = pvals.resolve(default_context, default_variables)
234
+ assert_nil params['sql-file']
235
+ end
236
+
237
+ # DestTableParam (9)
238
+
239
+ test "DestTableParam (*.job)" do
240
+ decls = wrap_decl DestTableParam.new
241
+ pvals = apply_values(decls, {'dest-table' => 'schemaA.tableA'})
242
+ params = pvals.resolve(default_context, default_variables)
243
+ assert_equal TableSpec.new('schemaA', 'tableA'), params['dest-table']
244
+ assert_equal 'schemaA.tableA', params.variables['dest_table']
245
+ end
246
+
247
+ test "DestTableParam (--opt)" do
248
+ decls = wrap_decl DestTableParam.new(optional: false)
249
+ pvals = apply_options(decls, ['--dest-table=schemaA.tableA'])
250
+ params = pvals.resolve(default_context, default_variables)
251
+ assert_equal TableSpec.new('schemaA', 'tableA'), params['dest-table']
252
+ assert_equal 'schemaA.tableA', params.variables['dest_table']
253
+ end
254
+
255
+ test "DestTableParam (default value)" do
256
+ decls = wrap_decl DestTableParam.new
257
+ pvals = apply_values(decls, {})
258
+ params = pvals.resolve(default_context, default_variables)
259
+ assert_nil params['dest-table']
260
+ assert_false params.variables.bound?('dest_table')
261
+ end
262
+
263
+ test "DestTableParam (variable expansion)" do
264
+ decls = wrap_decl DestTableParam.new
265
+ pvals = apply_values(decls, {'dest-table' => '$s.t'})
266
+ vars = ResolvedVariables.new
267
+ vars.add ResolvedVariable.new('s', 'SCH')
268
+ params = pvals.resolve(default_context, vars)
269
+ assert_equal TableSpec.new('SCH', 't'), params['dest-table']
270
+ assert_equal 'SCH.t', params.variables['dest_table']
271
+ end
272
+
273
+ test "DestTableParam (no such variable)" do
274
+ decls = wrap_decl DestTableParam.new
275
+ pvals = apply_values(decls, {'dest-table' => '$s.t'})
276
+ assert_raise(ParameterError) {
277
+ pvals.resolve(default_context, default_variables)
278
+ }
279
+ end
280
+
281
+ # SrcTableParam (9)
282
+
283
+ test "SrcTableParam (*.job)" do
284
+ decls = wrap_decl SrcTableParam.new
285
+ pvals = apply_values(decls, {'src-tables' => {'a' => '$s.A', 'b' => 'B'}})
286
+ vars = ResolvedVariables.new
287
+ vars.add ResolvedVariable.new('s', 'SCH')
288
+ params = pvals.resolve(default_context, vars)
289
+ srcs = {'a' => TableSpec.new('SCH', 'A'), 'b' => TableSpec.new(nil, 'B')}
290
+ assert_equal srcs, params['src-tables']
291
+ assert_equal 'SCH.A', params.variables['a']
292
+ assert_equal 'B', params.variables['b']
293
+ end
294
+
295
+ test "SrcTableParam (--opt)" do
296
+ decls = wrap_decl SrcTableParam.new
297
+ pvals = apply_options(decls, ['--src-table=a:A', '--src-table=b:B'])
298
+ params = pvals.resolve(default_context, default_variables)
299
+ srcs = {'a' => TableSpec.new(nil, 'A'), 'b' => TableSpec.new(nil, 'B')}
300
+ assert_equal srcs, params['src-tables']
301
+ assert_equal 'A', params.variables['a']
302
+ assert_equal 'B', params.variables['b']
303
+ end
304
+
305
+ test "SrcTableParam (default value)" do
306
+ decls = wrap_decl SrcTableParam.new
307
+ pvals = apply_values(decls, {})
308
+ params = pvals.resolve(default_context, default_variables)
309
+ assert_equal({}, params['src-tables'])
310
+ assert_false params.variables.bound?('a')
311
+ assert_false params.variables.bound?('b')
312
+ end
313
+
314
+ # DestFileParam (7)
315
+
316
+ test "DestFileParam (*.job)" do
317
+ decls = wrap_decl DestFileParam.new
318
+ pvals = apply_values(decls, {'dest-file' => '/some/path.txt'})
319
+ params = pvals.resolve(default_context, default_variables)
320
+ assert_equal Pathname.new('/some/path.txt'), params['dest-file']
321
+ end
322
+
323
+ test "DestFileParam (--opt)" do
324
+ decls = wrap_decl DestFileParam.new
325
+ pvals = apply_options(decls, ['--dest-file=/some/path.txt'])
326
+ params = pvals.resolve(default_context, default_variables)
327
+ assert_equal Pathname.new('/some/path.txt'), params['dest-file']
328
+ end
329
+
330
+ test "DestFileParam (no value error)" do
331
+ decls = wrap_decl DestFileParam.new
332
+ pvals = apply_values(decls, {})
333
+ assert_raise(ParameterError) {
334
+ pvals.resolve(default_context, default_variables)
335
+ }
336
+ end
337
+
338
+ # SrcFileParam (2)
339
+
340
+ test "SrcFileParam (*.job)" do
341
+ decls = wrap_decl SrcFileParam.new
342
+ pvals = apply_values(decls, {'src-file' => '/some/path.txt'})
343
+ params = pvals.resolve(default_context, default_variables)
344
+ assert_equal Pathname.new('/some/path.txt'), params['src-file']
345
+ end
346
+
347
+ test "SrcFileParam (--opt)" do
348
+ decls = wrap_decl SrcFileParam.new
349
+ pvals = apply_options(decls, ['--src-file=/some/path.txt'])
350
+ params = pvals.resolve(default_context, default_variables)
351
+ assert_equal Pathname.new('/some/path.txt'), params['src-file']
352
+ end
353
+
354
+ test "SrcFileParam (no value error)" do
355
+ decls = wrap_decl SrcFileParam.new
356
+ pvals = apply_values(decls, {})
357
+ assert_raise(ParameterError) {
358
+ pvals.resolve(default_context, default_variables)
359
+ }
360
+ end
361
+
362
+ # KeyValuePairsParam (3)
363
+
364
+ test "KeyValuePairsParam (*.job)" do
365
+ decls = wrap_decl KeyValuePairsParam.new('grant', 'KEY:VALUE', 'GRANT table after SQL is executed.')
366
+ pvals = apply_values(decls, {'grant' => {'on'=>'tbl', 'to'=>'$user'}})
367
+ vars = ResolvedVariables.new
368
+ vars.add ResolvedVariable.new('user', 'group gg')
369
+ params = pvals.resolve(default_context, vars)
370
+ assert_equal({'on'=>'tbl', 'to'=>'group gg'}, params['grant'])
371
+ end
372
+
373
+ test "KeyValuePairsParam (default value)" do
374
+ decls = wrap_decl KeyValuePairsParam.new('grant', 'KEY:VALUE', 'GRANT table after SQL is executed.')
375
+ pvals = apply_values(decls, {})
376
+ params = pvals.resolve(default_context, default_variables)
377
+ assert_nil params['grant']
378
+ end
379
+
380
+ # StringListParam (1)
381
+
382
+ test "StringListParam (*.job)" do
383
+ decls = wrap_decl StringListParam.new('args', 'ARG', 'Command line arguments.', publish: true)
384
+ pvals = apply_values(decls, {'args' => ['a', '$basedir', 'c']})
385
+ vars = ResolvedVariables.new
386
+ vars.add ResolvedVariable.new('basedir', '/base/dir')
387
+ params = pvals.resolve(default_context, vars)
388
+ assert_equal ['a', '/base/dir', 'c'], params['args']
389
+ assert_equal 'a /base/dir c', params.variables['args']
390
+ end
391
+
392
+ test "StringListParam (missing value)" do
393
+ decls = wrap_decl StringListParam.new('args', 'ARG', 'Command line arguments.')
394
+ pvals = apply_values(decls, {})
395
+ assert_raise(ParameterError) {
396
+ pvals.resolve(default_context, default_variables)
397
+ }
398
+ end
399
+
400
+ end
401
+ end
@@ -0,0 +1,114 @@
1
+ require 'test/unit'
2
+ require 'bricolage/job'
3
+ require 'bricolage/context'
4
+ require 'bricolage/variables'
5
+ require 'bricolage/parameters'
6
+ require 'optparse'
7
+ require 'pp'
8
+
9
+ module Bricolage
10
+ class TestVaribles < Test::Unit::TestCase
11
+ DummyFS = Struct.new(:home_path)
12
+ class DummyContextForGvarTest < Context
13
+ attr_accessor :variable_yml_vars
14
+ alias load_global_variables variable_yml_vars
15
+ end
16
+
17
+ test "global variable precedence" do
18
+ opt_gvars = Variables.new
19
+ opt_gvars.add Variable.new('var_global_opt', 'loc_global_opt')
20
+ fs = DummyFS.new('/home/path')
21
+ ctx = DummyContextForGvarTest.new(fs, 'development', global_variables: opt_gvars)
22
+ ctx.variable_yml_vars = Variables.define {|vars|
23
+ vars.add Variable.new('var_variable_yml', 'loc_variable_yml')
24
+ vars.add Variable.new('var_global_opt', 'loc_variable_yml')
25
+ }
26
+ result = ctx.global_variables
27
+
28
+ assert_equal 'loc_variable_yml', result['var_variable_yml']
29
+ assert_equal 'loc_global_opt', result['var_global_opt']
30
+ end
31
+
32
+ DummyContext = Struct.new(:global_variables)
33
+ class DummyContext
34
+ def job_dir
35
+ '/job/dir'
36
+ end
37
+ end
38
+
39
+ class DummyJobClass
40
+ def get_parameters
41
+ Parameters::Declarations.new
42
+ end
43
+
44
+ def invoke_parameters_filter(job)
45
+ end
46
+
47
+ def get_declarations(params)
48
+ Declarations.new
49
+ end
50
+
51
+ def get_script(params)
52
+ DummyScript.new
53
+ end
54
+ end
55
+
56
+ class DummyScript
57
+ def bind(ctx, vars)
58
+ vars
59
+ end
60
+ end
61
+
62
+ test "variable precedence (*.job)" do
63
+ gvars = Variables.new
64
+ gvars.add Variable.new('ow_global_variable', 'loc_global_variable')
65
+ gvars.add Variable.new('ow_rest_var', 'loc_global_variable')
66
+ gvars.add Variable.new('ow_job_opt', 'loc_global_variable')
67
+ ctx = DummyContext.new(gvars)
68
+ job_class = DummyJobClass.new
69
+ job = Job.new('varprec', job_class, ctx)
70
+ job.init_global_variables
71
+ job.bind_parameters({
72
+ 'ow_rest_var' => 'loc_rest_var',
73
+ 'ow_job_opt' => 'loc_rest_var'
74
+ })
75
+ job.parsing_options {|h|
76
+ opts = OptionParser.new
77
+ h.define_options(opts)
78
+ opts.parse!(['-v', 'ow_job_opt=loc_job_opt'])
79
+ }
80
+ job.compile
81
+
82
+ assert_equal 'loc_global_variable', job.variables['ow_global_variable']
83
+ assert_equal 'loc_rest_var', job.variables['ow_rest_var']
84
+ assert_equal 'loc_job_opt', job.variables['ow_job_opt']
85
+ end
86
+
87
+ test "lazy reference resolution" do
88
+ gvars = Variables.new
89
+ gvars.add Variable.new('gvar', 'GVAR')
90
+ gvars.add Variable.new('rest_var', '*global*')
91
+ gvars.add Variable.new('job_opt', '*global*')
92
+ gvars.add Variable.new('ref_gvar', '$gvar')
93
+ gvars.add Variable.new('ref_rest_var', '$rest_var')
94
+ gvars.add Variable.new('ref_job_opt', '$job_opt')
95
+ ctx = DummyContext.new(gvars)
96
+ job_class = DummyJobClass.new
97
+ job = Job.new('lazyres', job_class, ctx)
98
+ job.init_global_variables
99
+ job.bind_parameters({
100
+ 'rest_var' => 'REST_VAR'
101
+ })
102
+ job.parsing_options {|h|
103
+ opts = OptionParser.new
104
+ h.define_options(opts)
105
+ opts.parse!(['-v', 'job_opt=JOB_OPT'])
106
+ }
107
+ job.compile
108
+
109
+ assert_equal 'GVAR', job.variables['ref_gvar']
110
+ assert_equal 'REST_VAR', job.variables['ref_rest_var']
111
+ assert_equal 'JOB_OPT', job.variables['ref_job_opt']
112
+ end
113
+ end
114
+ end