pione 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.travis.yml +3 -0
- data/History.txt +15 -0
- data/Rakefile +4 -0
- data/doc/man/pione-action-list.md +23 -0
- data/doc/man/pione-action.md +37 -0
- data/doc/man/pione-clean.md +56 -0
- data/doc/man/pione-compiler.md +39 -0
- data/doc/man/pione-update-package-info.md +38 -0
- data/example/DeferredChoice/DeferredChoice.pione +6 -4
- data/example/DeferredChoice/pione-package.json +15 -0
- data/example/FeatureExample/FeatureExample.pione +2 -0
- data/example/FeatureExample/pione-package.json +15 -0
- data/example/LoopByTouch/LoopByTouch.pione +2 -0
- data/example/LoopByTouch/pione-package.json +18 -0
- data/example/LucasNumber/LucasNumber.pione +6 -4
- data/example/LucasNumber/pione-package.json +15 -0
- data/example/MakePair/MakePair.pione +2 -0
- data/example/MakePair/pione-package.json +17 -0
- data/example/MakePair/scenario/case1/Scenario.pione +1 -0
- data/example/MakePair/scenario/case1/pione-scenario.json +47 -0
- data/example/MakePair/scenario/case2/Scenario.pione +1 -0
- data/example/MakePair/scenario/case2/pione-scenario.json +22 -0
- data/example/MakePair/scenario/case3/Scenario.pione +1 -0
- data/example/MakePair/scenario/case3/pione-scenario.json +43 -0
- data/example/OddSelector/OddSelector.pione +2 -0
- data/example/OddSelector/pione-package.json +15 -0
- data/example/OddSelector/scenario/Scenario.pione +1 -0
- data/example/OddSelector/{data → scenario/input}/1.i +0 -0
- data/example/OddSelector/{data → scenario/input}/10.i +0 -0
- data/example/OddSelector/{data → scenario/input}/2.i +0 -0
- data/example/OddSelector/{data → scenario/input}/3.i +0 -0
- data/example/OddSelector/{data → scenario/input}/4.i +0 -0
- data/example/OddSelector/{data → scenario/input}/5.i +0 -0
- data/example/OddSelector/{data → scenario/input}/6.i +0 -0
- data/example/OddSelector/{data → scenario/input}/7.i +0 -0
- data/example/OddSelector/{data → scenario/input}/8.i +0 -0
- data/example/OddSelector/{data → scenario/input}/9.i +0 -0
- data/example/OddSelector/scenario/output/1.res +0 -0
- data/example/OddSelector/scenario/output/3.res +0 -0
- data/example/OddSelector/scenario/output/5.res +0 -0
- data/example/OddSelector/scenario/output/7.res +0 -0
- data/example/OddSelector/scenario/output/9.res +0 -0
- data/example/OddSelector/scenario/pione-scenario.json +23 -0
- data/example/PegasusWMS/Merge/Merge.pione +3 -1
- data/example/PegasusWMS/Merge/pione-package.json +15 -0
- data/example/PegasusWMS/Pipeline/Pipeline.pione +2 -0
- data/example/PegasusWMS/Pipeline/pione-package.json +15 -0
- data/example/PegasusWMS/Split/Split.pione +2 -0
- data/example/PegasusWMS/Split/pione-package.json +15 -0
- data/example/{AbstractRule/AbstractRule.pione → SelectRuleByParam/SelectRuleByParam.pione} +4 -2
- data/example/SelectRuleByParam/pione-package.json +17 -0
- data/example/SelectRuleByParam/scenario/a/Scenario.pione +2 -0
- data/example/{AbstractRule → SelectRuleByParam}/scenario/a/output/message.txt +0 -0
- data/example/SelectRuleByParam/scenario/a/pione-scenario.json +10 -0
- data/example/SelectRuleByParam/scenario/b/Scenario.pione +2 -0
- data/example/{AbstractRule → SelectRuleByParam}/scenario/b/output/message.txt +0 -0
- data/example/SelectRuleByParam/scenario/b/pione-scenario.json +10 -0
- data/example/SelectRuleByParam/scenario/c/Scenario.pione +2 -0
- data/example/{AbstractRule → SelectRuleByParam}/scenario/c/output/message.txt +0 -0
- data/example/SelectRuleByParam/scenario/c/pione-scenario.json +10 -0
- data/example/Sum/Sum.pione +23 -21
- data/example/Sum/pione-package.json +15 -0
- data/example/Sum/scenario/Scenario.pione +1 -0
- data/example/Sum/{input → scenario/input}/list.txt +0 -0
- data/example/Sum/scenario/output/sum.txt +6 -0
- data/example/Sum/scenario/pione-scenario.json +10 -0
- data/lib/pione/agent/agent-exception.rb +11 -0
- data/lib/pione/agent/process-manager.rb +19 -7
- data/lib/pione/agent/task-worker.rb +2 -2
- data/lib/pione/command/option.rb +0 -1
- data/lib/pione/command/pione-action-list.rb +49 -0
- data/lib/pione/command/pione-action.rb +83 -0
- data/lib/pione/command/pione-client.rb +34 -10
- data/lib/pione/command/pione-compiler.rb +19 -1
- data/lib/pione/command/pione-package.rb +2 -0
- data/lib/pione/command/pione-task-worker.rb +3 -1
- data/lib/pione/command/pione-update-package-info.rb +53 -0
- data/lib/pione/command.rb +6 -4
- data/lib/pione/global/tuple-space-notifier-variable.rb +1 -1
- data/lib/pione/lang/environment.rb +47 -16
- data/lib/pione/lang/parameters.rb +6 -0
- data/lib/pione/literate-action/document.rb +25 -0
- data/lib/pione/literate-action/handler.rb +24 -0
- data/lib/pione/literate-action/parser.rb +54 -0
- data/lib/pione/literate-action.rb +10 -0
- data/lib/pione/location/data-location.rb +11 -3
- data/lib/pione/location/dropbox-location.rb +2 -0
- data/lib/pione/location/local-location.rb +4 -0
- data/lib/pione/package/package-exception.rb +17 -1
- data/lib/pione/package/package-handler.rb +13 -4
- data/lib/pione/package/scenario-handler.rb +9 -3
- data/lib/pione/package/scenario-info.rb +4 -3
- data/lib/pione/package/scenario-scanner.rb +11 -7
- data/lib/pione/rule-engine/basic-handler.rb +1 -1
- data/lib/pione/rule-engine/flow-handler.rb +6 -5
- data/lib/pione/test-helper/command-helper.rb +44 -1
- data/lib/pione/test-helper/internet-connectivity.rb +10 -0
- data/lib/pione/test-helper.rb +11 -10
- data/lib/pione/util/digest.rb +1 -1
- data/lib/pione/util/id.rb +1 -1
- data/lib/pione/util/indentation.rb +1 -1
- data/lib/pione/util/last-time.rb +20 -0
- data/lib/pione/util/misc.rb +7 -1
- data/lib/pione/util/pnml-compiler.rb +84 -13
- data/lib/pione/util.rb +1 -0
- data/lib/pione/version.rb +1 -1
- data/lib/pione.rb +17 -15
- data/man/pione-action-list.1 +23 -0
- data/man/pione-action.1 +45 -0
- data/man/pione-compiler.1 +48 -0
- data/man/pione-update-package-info.1 +43 -0
- data/pione.gemspec +1 -0
- data/test/command/spec_pione-action-list.rb +15 -0
- data/test/command/spec_pione-action.rb +24 -0
- data/test/command/spec_pione-client.rb +189 -0
- data/test/command/spec_pione-compiler.rb +28 -1
- data/test/command/spec_pione-update-package-info.rb +66 -0
- data/test/lang/data/literal-parser.yml +1 -0
- data/test/lang/spec_environment.rb +19 -0
- data/test/literate-action/data/D1.md +25 -0
- data/test/literate-action/data/HelloWorld.md +11 -0
- data/test/literate-action/spec_document.rb +20 -0
- data/test/literate-action/spec_handler.rb +28 -0
- data/test/literate-action/spec_parser.rb +51 -0
- data/test/package/spec_scenario-info.rb +2 -2
- data/test/package/spec_scenario-scanner.rb +3 -3
- data/test/util/data/pnml/Sequence.pnml +135 -135
- data/test/util/spec_pnml-compiler.rb +20 -9
- metadata +102 -39
- data/example/AbstractRule/package.yml +0 -7
- data/example/AbstractRule/scenario/a/scenario.yml +0 -4
- data/example/AbstractRule/scenario/b/scenario.yml +0 -4
- data/example/AbstractRule/scenario/c/scenario.yml +0 -4
- data/example/HelloWorld/package.yml +0 -6
- data/example/HelloWorld/scenario/scenario.yml +0 -3
- data/example/MakePair/package.yml +0 -8
- data/example/MakePair/scenario/case1/scenario.yml +0 -42
- data/example/MakePair/scenario/case2/scenario.yml +0 -17
- data/example/MakePair/scenario/case3/scenario.yml +0 -39
- data/example/PegasusWMS/Merge/package.yml +0 -2
- data/example/PegasusWMS/Pipeline/package.yml +0 -2
- data/example/PegasusWMS/Split/package.yml +0 -2
- data/example/SyntaxError/call_rule_error.pione +0 -6
- data/example/SyntaxError/feature_line_error.pione +0 -7
- data/example/SyntaxError/flow_block_error.pione +0 -5
- data/example/SyntaxError/input_line_error.pione +0 -6
- data/example/SyntaxError/invalid_rule_name.pione +0 -6
- data/example/SyntaxError/output_line_error.pione +0 -6
- data/example/SyntaxError/param_line_error.pione +0 -7
- data/example/SyntaxError/variable-binding-error.pione +0 -11
data/lib/pione/command.rb
CHANGED
@@ -17,10 +17,12 @@ require 'pione/command/pione-tuple-space-viewer'
|
|
17
17
|
require 'pione/command/pione-relay'
|
18
18
|
require 'pione/command/pione-relay-client-db'
|
19
19
|
require 'pione/command/pione-relay-account-db'
|
20
|
-
require 'pione/command/pione-clean'
|
20
|
+
require 'pione/command/pione-clean' # pione clean
|
21
21
|
require 'pione/command/pione-syntax-checker'
|
22
|
-
require 'pione/command/pione-log'
|
23
|
-
require 'pione/command/pione-val'
|
22
|
+
require 'pione/command/pione-log' # pione log
|
23
|
+
require 'pione/command/pione-val' # pione-val
|
24
24
|
require 'pione/command/pione-package'
|
25
25
|
require 'pione/command/pione-compiler'
|
26
|
-
|
26
|
+
require 'pione/command/pione-update-package-info' # pione update-package-info
|
27
|
+
require 'pione/command/pione-action' # pione action
|
28
|
+
require 'pione/command/pione-action-list' # pione action:list
|
@@ -51,7 +51,7 @@ module Pione
|
|
51
51
|
item.desc = "presence notification addresses"
|
52
52
|
item.init = ["255.255.255.255:56000"]
|
53
53
|
item.define_updater do |vals|
|
54
|
-
vals.map {|val| URI.parse("broadcast://%s" % val)}
|
54
|
+
vals.map {|val| val.is_a?(String) ? URI.parse("broadcast://%s" % val) : val}
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -9,7 +9,7 @@ module Pione
|
|
9
9
|
|
10
10
|
# Return true if the name with the package id is bound.
|
11
11
|
def bound?(package_id, name)
|
12
|
-
@table[package_id][name] || (@parent ? @parent.bound?(package_id, name) : false)
|
12
|
+
(@table.has_key?(package_id) and @table[package_id][name]) || (@parent ? @parent.bound?(package_id, name) : false)
|
13
13
|
end
|
14
14
|
|
15
15
|
# Find value of the reference recursively. We will raise
|
@@ -55,12 +55,10 @@ module Pione
|
|
55
55
|
# get value from parent table
|
56
56
|
return @parent.get_value(env, ref) if @parent
|
57
57
|
else
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
return val
|
63
|
-
end
|
58
|
+
# otherwise, find by parent package id
|
59
|
+
env.find_ancestor_ids(ref.package_id).each do |ancestor_id|
|
60
|
+
if val = get_value(env, ref.set(package_id: ancestor_id))
|
61
|
+
return val
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
@@ -94,6 +92,22 @@ module Pione
|
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
95
|
+
# Return all names that related to the package ID and ancestors.
|
96
|
+
#
|
97
|
+
# @return [Array<String>]
|
98
|
+
# all names in the table
|
99
|
+
def select_names_by(env, package_id)
|
100
|
+
names = @parent ? @parent.select_names_by(package_id) : []
|
101
|
+
target_ids = [package_id, *env.find_ancestor_ids(package_id)]
|
102
|
+
target_ids.each_with_object(names) do |target_id, names|
|
103
|
+
@table[target_id].keys.each do |name|
|
104
|
+
if not(names.include?(name))
|
105
|
+
names << name
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
97
111
|
def inspect
|
98
112
|
if @parent
|
99
113
|
"#%s(%s,%s)" % [self.class.name.split("::").last, @table, @parent.inspect]
|
@@ -256,10 +270,20 @@ module Pione
|
|
256
270
|
package_id_table[package_name]
|
257
271
|
end
|
258
272
|
|
259
|
-
|
273
|
+
# Find ancestor's IDs of the package ID. The way of ancestors search is depth-first.
|
274
|
+
def find_ancestor_ids(package_id)
|
275
|
+
ancestor_ids = []
|
260
276
|
if package = package_get(PackageExpr.new(package_id: package_id))
|
261
|
-
package.parent_ids
|
277
|
+
ancestor_ids += package.parent_ids
|
278
|
+
package.parent_ids.each do |parent_id|
|
279
|
+
find_ancestor_ids(parent_id).each do |ancestor_id|
|
280
|
+
if not(ancestor_ids.include?(ancestor_id))
|
281
|
+
ancestor_ids << ancestor_id
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
262
285
|
end
|
286
|
+
return ancestor_ids
|
263
287
|
end
|
264
288
|
|
265
289
|
# Create a new environment which tables are overlayed current tables.
|
@@ -274,11 +298,17 @@ module Pione
|
|
274
298
|
)
|
275
299
|
end
|
276
300
|
|
277
|
-
|
301
|
+
# Merge the parameter set as variables into this environment. Rebinding
|
302
|
+
# variables raise error, but it is ignored when force flag is true.
|
303
|
+
#
|
304
|
+
# @param param_set [Lang::ParameterSet]
|
305
|
+
# parameter set to be merged
|
306
|
+
# @option option
|
307
|
+
def merge_param_set(param_set, option={})
|
278
308
|
param_set.keys.each do |key|
|
279
309
|
var = Variable.new(name: key, package_id: current_package_id)
|
280
310
|
val = param_set[key]
|
281
|
-
variable_set(var, val)
|
311
|
+
option[:force] ? variable_set!(var, val) : variable_set(var, val)
|
282
312
|
end
|
283
313
|
return self
|
284
314
|
end
|
@@ -305,16 +335,17 @@ module Pione
|
|
305
335
|
set(current_package_id: package_id, current_definition: definition)
|
306
336
|
end
|
307
337
|
|
308
|
-
def make_root_rule(
|
309
|
-
# set
|
310
|
-
variable_set(Variable.new("
|
338
|
+
def make_root_rule(main_param_set)
|
339
|
+
# put variable of parameter set for main rule
|
340
|
+
variable_set(Variable.new("MAIN_PARAM_SET"), ParameterSetSequence.of(main_param_set))
|
341
|
+
|
311
342
|
# make root rule
|
312
|
-
Package::Document.parse(<<-PIONE, current_package_id, nil, nil, "*
|
343
|
+
Package::Document.parse(<<-PIONE, current_package_id, nil, nil, "*System*").eval(self)
|
313
344
|
Rule Root
|
314
345
|
input '*'.all or null
|
315
346
|
output '*'.all
|
316
347
|
Flow
|
317
|
-
rule Main.param($
|
348
|
+
rule Main.param($MAIN_PARAM_SET)
|
318
349
|
End
|
319
350
|
PIONE
|
320
351
|
rule_get(RuleExpr.new("Root"))
|
@@ -17,7 +17,13 @@ module Pione
|
|
17
17
|
set(table: table.merge(other.table))
|
18
18
|
end
|
19
19
|
|
20
|
+
# Return a parameter set that match the names.
|
20
21
|
def filter(names)
|
22
|
+
set(table: table.select{|key, _| names.include?(key)})
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return a parameter set excluding the names.
|
26
|
+
def delete_all(names)
|
21
27
|
set(table: table.reject{|key, _| names.include?(key)})
|
22
28
|
end
|
23
29
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Pione
|
2
|
+
module LiterateAction
|
3
|
+
class Document
|
4
|
+
def self.load(location)
|
5
|
+
new(location.read)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(src)
|
9
|
+
@action = Parser.parse(src)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return action names in the document.
|
13
|
+
def action_names
|
14
|
+
@action.keys
|
15
|
+
end
|
16
|
+
|
17
|
+
# Find target action fromt the name.
|
18
|
+
def find(name)
|
19
|
+
if action = @action[name]
|
20
|
+
Handler.new(action)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Pione
|
2
|
+
module LiterateAction
|
3
|
+
class Handler
|
4
|
+
def initialize(action)
|
5
|
+
@lang = action[:lang]
|
6
|
+
@content = action[:content]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Convert the action to a string.
|
10
|
+
def textize(domain_info)
|
11
|
+
@content.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
# Execute the action.
|
15
|
+
def execute(domain_info, dir=Location[Global.pwd])
|
16
|
+
text = textize(domain_info)
|
17
|
+
location = Location[Temppath.create]
|
18
|
+
location.write(("#!/usr/bin/env %s\n" % @lang) + text)
|
19
|
+
location.path.chmod(0700)
|
20
|
+
`cd #{dir.path}; #{location.path}`
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Pione
|
2
|
+
module LiterateAction
|
3
|
+
class Parser
|
4
|
+
# Parse the source string and return the result.
|
5
|
+
def self.parse(src)
|
6
|
+
new(src).parse
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(src)
|
10
|
+
@src = src
|
11
|
+
end
|
12
|
+
|
13
|
+
# Parse the source string.
|
14
|
+
def parse
|
15
|
+
@parsed = Kramdown::Parser::GFM.parse(@src)
|
16
|
+
current_name = nil
|
17
|
+
root = @parsed.first
|
18
|
+
root.children.each_with_object(Hash.new) do |elt, action|
|
19
|
+
if name = find_rule_name(elt)
|
20
|
+
current_name = name
|
21
|
+
next
|
22
|
+
end
|
23
|
+
|
24
|
+
if current_name
|
25
|
+
lang, content = find_action(elt)
|
26
|
+
if content
|
27
|
+
action[current_name] ||= {content: ""}
|
28
|
+
action[current_name][:lang] = lang
|
29
|
+
action[current_name][:content] << content
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Find a rule name from the element.
|
38
|
+
def find_rule_name(elt)
|
39
|
+
if elt.type == :header and elt.options[:level] == 2
|
40
|
+
elt.options[:raw_text]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Find an action from the element.
|
45
|
+
def find_action(elt)
|
46
|
+
if elt.type == :codeblock
|
47
|
+
if elt.attr["class"] and elt.attr["class"].start_with?("language-")
|
48
|
+
return [elt.attr["class"].sub("language-", ""), elt.value]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -191,15 +191,23 @@ module Pione
|
|
191
191
|
raise NotImplementedError
|
192
192
|
end
|
193
193
|
|
194
|
-
# Return
|
194
|
+
# Return ctime of the location.
|
195
195
|
#
|
196
196
|
# @return [Time]
|
197
|
-
#
|
197
|
+
# ctime
|
198
|
+
def ctime
|
199
|
+
raise NotImplementedError
|
200
|
+
end
|
201
|
+
|
202
|
+
# Return mtime of the location.
|
203
|
+
#
|
204
|
+
# @return [Time]
|
205
|
+
# mtime
|
198
206
|
def mtime
|
199
207
|
raise NotImplementedError
|
200
208
|
end
|
201
209
|
|
202
|
-
# Set
|
210
|
+
# Set mtime of the location.
|
203
211
|
#
|
204
212
|
# @return [void]
|
205
213
|
def mtime=(time)
|
@@ -31,7 +31,23 @@ module Pione
|
|
31
31
|
class InvalidPackage < PackageError; end
|
32
32
|
|
33
33
|
# InvalidScenario raises when the package is something bad.
|
34
|
-
class InvalidScenario < PackageError
|
34
|
+
class InvalidScenario < PackageError
|
35
|
+
def initialize(location, reason)
|
36
|
+
@location = location
|
37
|
+
@reason = reason
|
38
|
+
end
|
39
|
+
|
40
|
+
def message
|
41
|
+
"%<path>s is an invalid scenario document: %<reason>s" % args
|
42
|
+
end
|
43
|
+
|
44
|
+
def args
|
45
|
+
{
|
46
|
+
:path => @location.path,
|
47
|
+
:reason => @reason
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
35
51
|
|
36
52
|
class DatabaseError < PackageError; end
|
37
53
|
end
|
@@ -4,13 +4,22 @@ module Pione
|
|
4
4
|
class PackageHandler
|
5
5
|
class << self
|
6
6
|
# Update package info file and scenario info files.
|
7
|
-
def write_info_files(location)
|
7
|
+
def write_info_files(location, option={})
|
8
|
+
# scan the package directory
|
8
9
|
package_info = PackageScanner.new(location).scan
|
9
|
-
(location +
|
10
|
-
|
10
|
+
last_time = Util::LastTime.get(package_info.filepaths.map{|path| location + path})
|
11
|
+
|
12
|
+
# update the package info file
|
13
|
+
info_location = location + "pione-package.json"
|
14
|
+
if option[:force] or not(info_location.exist?) or last_time > info_location.mtime
|
15
|
+
info_location.write(JSON.pretty_generate(package_info))
|
16
|
+
Log::SystemLog.info("update the package info file: %s" % info_location.address)
|
17
|
+
end
|
18
|
+
|
19
|
+
# write scenario info files
|
11
20
|
package_info.scenarios.each do |scenario|
|
12
21
|
scenario_info = ScenarioScanner.new(location + scenario).scan
|
13
|
-
ScenarioHandler.new(location + scenario, scenario_info).write_info_file
|
22
|
+
ScenarioHandler.new(location + scenario, scenario_info).write_info_file(option)
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|
@@ -17,9 +17,15 @@ module Pione
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# Write an information file for the scenario.
|
20
|
-
def write_info_file
|
21
|
-
(@location +
|
22
|
-
|
20
|
+
def write_info_file(option={})
|
21
|
+
last_time = Util::LastTime.get(@info.filepaths.map{|path| @location + path})
|
22
|
+
|
23
|
+
# update the scenario info file
|
24
|
+
location = @location + "pione-scenario.json"
|
25
|
+
if option[:force] or not(location.exist?) or last_time > location.mtime
|
26
|
+
location.write(JSON.pretty_generate(@info))
|
27
|
+
Log::SystemLog.info("update the scenario info file: %s" % location.address)
|
28
|
+
end
|
23
29
|
end
|
24
30
|
|
25
31
|
# Return input location of the scenario. If the scenario doesn't have
|
@@ -2,7 +2,7 @@ module Pione
|
|
2
2
|
module Package
|
3
3
|
class ScenarioInfo < StructX
|
4
4
|
member :name
|
5
|
-
member :
|
5
|
+
member :textual_param_sets
|
6
6
|
member :inputs, default: lambda {Array.new}
|
7
7
|
member :outputs, default: lambda {Array.new}
|
8
8
|
|
@@ -10,12 +10,13 @@ module Pione
|
|
10
10
|
# location of the file.
|
11
11
|
def self.read(src)
|
12
12
|
data = JSON.load(src.is_a?(Location::DataLocation) ? src.read : src)
|
13
|
-
new(name: data["ScenarioName"],
|
13
|
+
new(name: data["ScenarioName"], textual_param_sets: data["ParamSet"], inputs: data["Inputs"], outputs: data["Outputs"])
|
14
14
|
end
|
15
15
|
|
16
16
|
# Return file paths of the scenario.
|
17
17
|
def filepaths
|
18
18
|
list = []
|
19
|
+
list << "Scenario.pione"
|
19
20
|
list += inputs
|
20
21
|
list += outputs
|
21
22
|
return list
|
@@ -24,7 +25,7 @@ module Pione
|
|
24
25
|
def to_json(*args)
|
25
26
|
data = Hash.new
|
26
27
|
data["ScenarioName"] = name
|
27
|
-
data["ParamSet"] =
|
28
|
+
data["ParamSet"] = textual_param_sets
|
28
29
|
data["Inputs"] = inputs
|
29
30
|
data["Outputs"] = outputs
|
30
31
|
data.to_json(*args)
|
@@ -29,20 +29,20 @@ module Pione
|
|
29
29
|
name, param_set = scan_annotations
|
30
30
|
inputs = scan_data_dir("input")
|
31
31
|
outputs = scan_data_dir("output")
|
32
|
-
ScenarioInfo.new(name: name,
|
32
|
+
ScenarioInfo.new(name: name, textual_param_sets: param_set, inputs: inputs, outputs: outputs)
|
33
33
|
end
|
34
|
-
rescue Parslet::ParseFailed => e
|
35
|
-
raise InvalidScenario.new("invalid scenario document because of parser failed: %s" % e.message)
|
36
34
|
end
|
37
35
|
|
38
36
|
# Scan annotations from scenario file and return scenario name and
|
39
37
|
# parameter set.
|
40
38
|
def scan_annotations
|
39
|
+
location = @location + "Scenario.pione"
|
40
|
+
|
41
41
|
# setup fake language environment
|
42
42
|
env = Lang::Environment.new.setup_new_package("ScenarioScanner")
|
43
43
|
|
44
44
|
# parse the scenario document
|
45
|
-
Document.load(env,
|
45
|
+
Document.load(env, location, nil, nil, nil, @location + "Scenario.pione")
|
46
46
|
|
47
47
|
# get name and parameter set from fake package's annotations
|
48
48
|
annotations = env.package_get(Lang::PackageExpr.new(package_id: env.current_package_id)).annotations
|
@@ -50,6 +50,8 @@ module Pione
|
|
50
50
|
param_set = find_param_set(annotations)
|
51
51
|
|
52
52
|
return name, param_set
|
53
|
+
rescue Parslet::ParseFailed => e
|
54
|
+
raise InvalidScenario.new(location, "Parser failed: " + e.message)
|
53
55
|
end
|
54
56
|
|
55
57
|
# Scan data files.
|
@@ -67,15 +69,16 @@ module Pione
|
|
67
69
|
|
68
70
|
# Find "ScenarioName" annotaion.
|
69
71
|
def find_name(annotations)
|
72
|
+
location = @location + "Scenario.pione"
|
70
73
|
names = annotations.select {|annotation| annotation.annotation_type == "ScenarioName"}
|
71
74
|
case names.size
|
72
75
|
when 0
|
73
|
-
raise InvalidScenario.new("No scenario name
|
76
|
+
raise InvalidScenario.new(location, "No scenario name exists.")
|
74
77
|
when 1
|
75
78
|
names.first.value
|
76
79
|
else
|
77
80
|
name_list = names.map {|name| name.value}.join(", ")
|
78
|
-
raise InvalidScenario.new("
|
81
|
+
raise InvalidScenario.new(location, "Duplicated scenario name found." % name_list)
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
@@ -88,7 +91,8 @@ module Pione
|
|
88
91
|
when 1
|
89
92
|
param_sets.first.value
|
90
93
|
else
|
91
|
-
|
94
|
+
location = @location + "Scenario.pione"
|
95
|
+
raise InvalidScenario.new(location, "Duplicated parameter set found.")
|
92
96
|
end
|
93
97
|
end
|
94
98
|
end
|
@@ -129,7 +129,7 @@ module Pione
|
|
129
129
|
# Make a task tuple from the application.
|
130
130
|
def make_tuple(caller_id)
|
131
131
|
features = rule_condition.features.inject(Lang::FeatureSequence.new) do |f, expr|
|
132
|
-
f +
|
132
|
+
f + expr.eval(env)
|
133
133
|
end
|
134
134
|
TupleSpace::TaskTuple.new(
|
135
135
|
digest,
|
@@ -229,7 +229,7 @@ module Pione
|
|
229
229
|
pieces.each do |param_set|
|
230
230
|
### merge default parameter values ####
|
231
231
|
# setup task's environment by parameter set
|
232
|
-
_env = plain_env.layer.
|
232
|
+
_env = plain_env.layer.merge_param_set(param_set)
|
233
233
|
_env.set(current_package_id: rule.package_id || env.current_package_id)
|
234
234
|
|
235
235
|
# get task's condition
|
@@ -239,9 +239,9 @@ module Pione
|
|
239
239
|
_param_set = param_set.merge_default_values(rule_condition)
|
240
240
|
|
241
241
|
# handle parameter distribution
|
242
|
-
_param_set.expand do |expanded_param_set|
|
242
|
+
_param_set.eval(_env).expand do |expanded_param_set|
|
243
243
|
# rebuild environment by expanded param set
|
244
|
-
_env = plain_env.layer.
|
244
|
+
_env = plain_env.layer.merge_param_set(expanded_param_set)
|
245
245
|
_env.set(current_package_id: rule.package_id || env.current_package_id)
|
246
246
|
|
247
247
|
# get task's condition
|
@@ -437,7 +437,8 @@ module Pione
|
|
437
437
|
# Wait until tasks completed.
|
438
438
|
def wait_task_completion(tasks)
|
439
439
|
tasks.each do |task|
|
440
|
-
# wait to finish the
|
440
|
+
# wait to finish the distributed task, note that finished tuple is in
|
441
|
+
# the task domain
|
441
442
|
finished = read(TupleSpace::FinishedTuple.new(domain: task.domain_id))
|
442
443
|
|
443
444
|
### task completion processing ###
|
@@ -54,7 +54,7 @@ module Pione
|
|
54
54
|
private
|
55
55
|
|
56
56
|
# Run the command execution action.
|
57
|
-
def execute(options, &b)
|
57
|
+
def execute(*options, &b)
|
58
58
|
# initialize exit status
|
59
59
|
Global.exit_status = true
|
60
60
|
|
@@ -88,5 +88,48 @@ module Pione
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
91
|
+
|
92
|
+
class PioneClientRunner < StructX
|
93
|
+
member :title
|
94
|
+
member :template, default: "%s"
|
95
|
+
member :args
|
96
|
+
member :base, default: lambda {Pione::Location[Temppath.mkdir]}
|
97
|
+
member :default_arguments
|
98
|
+
member :context
|
99
|
+
|
100
|
+
def self.test(context, &b)
|
101
|
+
# with client mode
|
102
|
+
new(context: context).tap do |runner|
|
103
|
+
runner.default_arguments = ["-o", runner.base.path.to_s]
|
104
|
+
b.call(runner)
|
105
|
+
end
|
106
|
+
|
107
|
+
# with stand alone mode
|
108
|
+
new(context: context, template: "%s with stand alone mode").tap do |runner|
|
109
|
+
runner.default_arguments = ["-o", runner.base.path.to_s, "--stand-alone"]
|
110
|
+
b.call(runner)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def run(&b)
|
115
|
+
_args = args
|
116
|
+
_base = base
|
117
|
+
context.it(template % title) do
|
118
|
+
TestHelper::Command.succeed do
|
119
|
+
Pione::Command::PioneClient.run(_args)
|
120
|
+
end
|
121
|
+
b.call(_base)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def timeout(sec)
|
126
|
+
_args = args + ["--timeout", sec.to_s]
|
127
|
+
context.it(template % title) do
|
128
|
+
TestHelper::Command.fail do
|
129
|
+
Pione::Command::PioneClient.run(_args)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
91
134
|
end
|
92
135
|
end
|
data/lib/pione/test-helper.rb
CHANGED
@@ -28,16 +28,17 @@ module Pione
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# load test helpers
|
31
|
-
require "pione/test-helper/extension"
|
32
|
-
require "pione/test-helper/webserver"
|
33
|
-
require "pione/test-helper/location-helper"
|
34
|
-
require "pione/test-helper/command-helper"
|
35
|
-
require "pione/test-helper/parser-helper"
|
36
|
-
require "pione/test-helper/transformer-helper"
|
37
|
-
require "pione/test-helper/lang-helper"
|
38
|
-
require "pione/test-helper/package-helper"
|
39
|
-
require "pione/test-helper/tuple-helper"
|
40
|
-
require "pione/test-helper/tuple-space-helper"
|
31
|
+
require "pione/test-helper/extension" # extensions for test
|
32
|
+
require "pione/test-helper/webserver" # fake HTTP server
|
33
|
+
require "pione/test-helper/location-helper" # location test helper
|
34
|
+
require "pione/test-helper/command-helper" # command test helper
|
35
|
+
require "pione/test-helper/parser-helper" # parser test utility
|
36
|
+
require "pione/test-helper/transformer-helper" # transformer test utility
|
37
|
+
require "pione/test-helper/lang-helper" # language test method
|
38
|
+
require "pione/test-helper/package-helper" # pakcage test
|
39
|
+
require "pione/test-helper/tuple-helper" # tuple test
|
40
|
+
require "pione/test-helper/tuple-space-helper" # tuple space
|
41
|
+
require "pione/test-helper/internet-connectivity" # check internet connection
|
41
42
|
|
42
43
|
# extend bacon's context
|
43
44
|
class Bacon::Context
|
data/lib/pione/util/digest.rb
CHANGED
@@ -10,7 +10,7 @@ module Pione
|
|
10
10
|
else
|
11
11
|
_inputs = "%s,..." % inputs.flatten[0..2].map{|i| i.name}.join(",")
|
12
12
|
end
|
13
|
-
_param_set = param_set.
|
13
|
+
_param_set = param_set.delete_all(["I", "INPUT", "O", "OUTPUT", "*"])
|
14
14
|
_param_set = _param_set.map{|k,v| "%s:%s" % [k, v.textize]}.join(",")
|
15
15
|
"&%s:%s([%s],{%s})" % [package_id, rule_name, _inputs, _param_set]
|
16
16
|
end
|
data/lib/pione/util/id.rb
CHANGED
@@ -5,7 +5,7 @@ module Pione
|
|
5
5
|
# Make a task id by input data names and parameters.
|
6
6
|
def generate(inputs, params)
|
7
7
|
# NOTE: auto variables are ignored
|
8
|
-
param_set = params.
|
8
|
+
param_set = params.delete_all(["I", "INPUT", "O", "OUTPUT", "*"])
|
9
9
|
inputs = inputs.map {|t| t.is_a?(TupleSpace::DataTuple) ? t.name : t}
|
10
10
|
Digest::MD5.hexdigest("%s::%s" % [inputs.join(":"), param_set.textize])
|
11
11
|
end
|