bricolage 5.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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