tla-trace-filter 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.org +66 -0
- data/VERSION +1 -0
- data/bin/tla-trace-filter.rb +5 -0
- data/lib/cli/cli.rb +563 -0
- data/lib/filter/filter.rb +134 -0
- data/lib/parser/grammar.treetop +132 -0
- data/lib/parser/node_extensions.rb +267 -0
- data/lib/parser/parser.rb +85 -0
- data/lib/render/render.rb +510 -0
- data/lib/tla-trace-filter.rb +6 -0
- data/lib/util/logger.rb +82 -0
- data/mustache/add-links-interface.mustache +33 -0
- data/mustache/add-links-state-dump.mustache +28 -0
- data/mustache/add-links-transition.mustache +14 -0
- data/mustache/add-links.mustache +43 -0
- data/mustache/api-call-default.mustache +14 -0
- data/mustache/api-call-init.mustache +70 -0
- data/mustache/api-call-input.mustache +20 -0
- data/mustache/api-call-link.mustache +2 -0
- data/mustache/api-call-main.mustache +86 -0
- data/mustache/api-call-output.mustache +18 -0
- data/mustache/api-call-return.mustache +13 -0
- data/mustache/api-call.mustache +34 -0
- data/spec/cli/cli_spec.rb +73 -0
- data/spec/filter/filter_spec.rb +53 -0
- data/spec/fixtures/interfaces.yaml +22 -0
- data/spec/fixtures/model.tla +1195 -0
- data/spec/fixtures/trace.txt +102 -0
- data/spec/parser/node_extensions_spec.rb +9 -0
- data/spec/parser/parser_spec.rb +392 -0
- data/spec/render/render_spec.rb +177 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/test_spec.rb +8 -0
- data/tla-trace-filter.gemspec +45 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b2804fbc967c6c2816038bd6f3b6a8cfee973484
|
4
|
+
data.tar.gz: 9fab9d64242a596da309fa119ef34401f608cc7b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 400432361333e1f8c3186c9ea77907877c1fc09ea7ee01c994f1b29d0f31ac15a39a5867422541c29dec1c4258136c700eb5d40072ee5ac9f8ff0437b7e9fd3c
|
7
|
+
data.tar.gz: 30366f9fade7597713f53e02d62bad8e37449ce5b0f249ddd87039191fc5562ccbd677ffb2bc211ed3f69e9b41ad4f9da145fca83ece7810cd659d14df5ae659
|
data/README.org
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
* =tla-sbuilder-trace= - Post process TLA-tools trace output
|
2
|
+
|
3
|
+
A command line filter utility for processing [[http://research.microsoft.com/en-us/um/people/lamport/tla/tools.html][TLA+ Tools]] output
|
4
|
+
resulting created when model checking [[[http://research.microsoft.com/en-us/um/people/lamport/tla/book.html][TLA+ language]]] formal model
|
5
|
+
generated using [[https://github.com/jarjuk/tla-sbuilder][sbuilder]] -tool.
|
6
|
+
|
7
|
+
The utility
|
8
|
+
|
9
|
+
|
10
|
+
* Installation
|
11
|
+
|
12
|
+
To install =tla-trace-filter= GEM create a =Gemfile= -file with the
|
13
|
+
content
|
14
|
+
|
15
|
+
#+BEGIN_SRC ruby :eval no
|
16
|
+
source "https://rubygems.org"
|
17
|
+
gem 'tla-trace-filter'
|
18
|
+
#+END_SRC
|
19
|
+
|
20
|
+
and run
|
21
|
+
|
22
|
+
#+BEGIN_SRC ruby :eval no
|
23
|
+
bundle install
|
24
|
+
#+END_SRC
|
25
|
+
|
26
|
+
* Usage
|
27
|
+
|
28
|
+
** Genrate traces :noexport:
|
29
|
+
|
30
|
+
** Add links to trace file
|
31
|
+
|
32
|
+
To add links to model checker trace output in file =gen/tlc.out=
|
33
|
+
outputted when model checking TLA+ language formal model code in file
|
34
|
+
=gen/setup1/tla/model.tla=
|
35
|
+
|
36
|
+
#+BEGIN_SRC ruby :eval no-export
|
37
|
+
bundle exec tla-trace-filter.rb add-links setup1
|
38
|
+
#+END_SRC
|
39
|
+
|
40
|
+
|
41
|
+
To embed links to trace output run:
|
42
|
+
|
43
|
+
#+BEGIN_SRC ruby :eval no-export
|
44
|
+
bundle exec tla-trace-filter.rb add-links setup1 --embed
|
45
|
+
#+END_SRC
|
46
|
+
|
47
|
+
|
48
|
+
To create API calls run:
|
49
|
+
|
50
|
+
#+BEGIN_SRC ruby :eval no
|
51
|
+
bundle exec tla-trace-filter.rb api-calls setup1
|
52
|
+
#+END_SRC
|
53
|
+
|
54
|
+
|
55
|
+
Location of the files and directories can be changes using command
|
56
|
+
line options. To get a list of available command and their options run:
|
57
|
+
|
58
|
+
bundle exec tla-trace-filter.rb help
|
59
|
+
|
60
|
+
|
61
|
+
** Create API trace
|
62
|
+
|
63
|
+
|
64
|
+
** Documentation
|
65
|
+
|
66
|
+
See [[https://cucumber.io][Cucumber]] tests in =features= -directory [[http://jarjuk.github.io/tla-trace-filter.html][github repo]].
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.3
|
data/lib/cli/cli.rb
ADDED
@@ -0,0 +1,563 @@
|
|
1
|
+
require_relative "../tla-trace-filter.rb"
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module TlaTraceFilter
|
7
|
+
class Cli < Thor
|
8
|
+
|
9
|
+
include TlaTraceFilter::Util::MyLogger
|
10
|
+
|
11
|
+
API_CALL_INIT = "api-call-init" # name mustache template called once
|
12
|
+
API_CALL_TEMPLATE = "api-call" # root template for command 'api-call'
|
13
|
+
ADD_LINKS_TEMPLATE = "add-links" # root template for command 'add-links'
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
VERSION_BANNER = <<~EOS
|
18
|
+
#{File.basename $0}: #{File.readlines( File.join File.dirname( __FILE__ ), "../../VERSION" ).first.gsub( /\n/, "" )}
|
19
|
+
EOS
|
20
|
+
|
21
|
+
MUSTACHE_DEFAULT = "mustache/"
|
22
|
+
MUSTACHE_OPTION= <<-EOS
|
23
|
+
Output is processed using mustache templates in directory
|
24
|
+
#{File.dirname __FILE__}/../../mustache. Mustache templates can be
|
25
|
+
overridden using templates in directory pointeted by line option
|
26
|
+
:mustache. Default = #{MUSTACHE_DEFAULT}
|
27
|
+
|
28
|
+
Parameter values ending with /-character are directories,
|
29
|
+
otherwise it is GEM name, where partials are in 'mustache'
|
30
|
+
sub-directory.
|
31
|
+
|
32
|
+
EOS
|
33
|
+
|
34
|
+
# ------------------------------------------------------------------
|
35
|
+
# @!group Attributes
|
36
|
+
|
37
|
+
no_commands do
|
38
|
+
|
39
|
+
# @!attribute [Filter] filtering to manage filtering state
|
40
|
+
def filtering
|
41
|
+
@filtering ||= TlaTraceFilter::Filter.new( options )
|
42
|
+
end
|
43
|
+
|
44
|
+
# @!attribute [Render] rendering tool outpu trace
|
45
|
+
#
|
46
|
+
# @param options [Hash] options with property :mustache
|
47
|
+
# prepended to partial search path
|
48
|
+
def rendering
|
49
|
+
@rendering ||= TlaTraceFilter::Render.new( options )
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# @!endgroup
|
55
|
+
|
56
|
+
|
57
|
+
# ------------------------------------------------------------------
|
58
|
+
# @!group Constructor
|
59
|
+
|
60
|
+
def initialize( *args )
|
61
|
+
super
|
62
|
+
@logger = getLogger( nil, options )
|
63
|
+
@logger.info "#{__method__}: initalized"
|
64
|
+
end
|
65
|
+
|
66
|
+
# @!endgroup
|
67
|
+
|
68
|
+
# ------------------------------------------------------------------
|
69
|
+
# @!group Enable shared options
|
70
|
+
|
71
|
+
# make two thor tasks share options?
|
72
|
+
# http://stackoverflow.com/questions/14346285/how-to-make-two-thor-tasks-share-options
|
73
|
+
|
74
|
+
class << self
|
75
|
+
def add_shared_option(name, options = {})
|
76
|
+
@shared_options = {} if @shared_options.nil?
|
77
|
+
@shared_options[name] = options
|
78
|
+
end
|
79
|
+
|
80
|
+
def shared_options(*option_names)
|
81
|
+
option_names.each do |option_name|
|
82
|
+
opt = @shared_options[option_name]
|
83
|
+
raise "Tried to access shared option '#{option_name}' but it was not previously defined" if opt.nil?
|
84
|
+
yield option_name, opt if block_given?
|
85
|
+
option option_name, opt
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# @!endgroup
|
91
|
+
|
92
|
+
# ------------------------------------------------------------------
|
93
|
+
# @!group Shared options
|
94
|
+
|
95
|
+
class_option :log, :aliases => "-l", :type =>:string, :default => nil,
|
96
|
+
:enum => [ "DEBUG", "INFO", "WARN", "ERROR" ],
|
97
|
+
:desc => "Set debug level "
|
98
|
+
|
99
|
+
|
100
|
+
class_option :logfile, :type =>:string,
|
101
|
+
:default => File.join(Dir.getwd, TlaTraceFilter::Util::MyLogger::LOGFILE),
|
102
|
+
:desc => "Set file for log output"
|
103
|
+
|
104
|
+
add_shared_option :state_dump, :default=>false, :type=>:boolean, :desc=>"Dump parsed state space states in JSON format"
|
105
|
+
|
106
|
+
add_shared_option :tla_dir, :type=>:string, :desc=>"Override default specification code dir gen/SETUP/tla"
|
107
|
+
add_shared_option :src_dir, :default=>"./solidity", :type=>:string, :desc=>"Source code root directory"
|
108
|
+
add_shared_option :filter_src, :aliases => "-f", :type => :boolean, :default => false
|
109
|
+
add_shared_option :mustache, :aliases => "-m", :type => :string, :desc => "Add a directory (ends with /-char) or GEM to search for mustache template", :default=> MUSTACHE_DEFAULT
|
110
|
+
add_shared_option :solc_line, :type => :boolean, :default=>false, :desc => "TRUE interpretes sourceLines as characters starting from source start"
|
111
|
+
add_shared_option :debug_mustache, :type => :boolean, :default=>false, :desc => "Raise exception if referencing non-existing property"
|
112
|
+
add_shared_option :embed, :type => :boolean, :default=>false, :desc => "TRUE adds link to trace output"
|
113
|
+
|
114
|
+
# @!endgroup
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
# ------------------------------------------------------------------
|
119
|
+
# @!group Commands
|
120
|
+
|
121
|
+
desc :version, "Output version"
|
122
|
+
def version()
|
123
|
+
puts VERSION_BANNER
|
124
|
+
end
|
125
|
+
|
126
|
+
desc "add-links SETUP [FILE]", "Add links for SETUP into trace output in FILE (- for STDIN)"
|
127
|
+
|
128
|
+
long_desc <<-EOF
|
129
|
+
|
130
|
+
Filter tla+tools trace output FILE (default 'gen/<setup>/tlc.out') and add
|
131
|
+
links 1) for transitions found in FILE pointing to specification
|
132
|
+
code 'model.tla' in directory 'gen/SETUP/tla' (override using
|
133
|
+
option :tla-dir) and 2) for source code references found in FILE
|
134
|
+
pointing to source files in directory 'solidity' (override using
|
135
|
+
option 'src-dir').
|
136
|
+
|
137
|
+
Links to source files are resolved using 'interface.yaml' YAML
|
138
|
+
file located in specification code directory (option :tla-dir).
|
139
|
+
|
140
|
+
#{MUSTACHE_OPTION}
|
141
|
+
EOF
|
142
|
+
shared_options :mustache
|
143
|
+
shared_options :debug_mustache
|
144
|
+
shared_options :tla_dir
|
145
|
+
shared_options :src_dir
|
146
|
+
shared_options :state_dump
|
147
|
+
shared_options :filter_src
|
148
|
+
shared_options :embed
|
149
|
+
shared_options :solc_line
|
150
|
+
def add_links( setup, file=nil )
|
151
|
+
|
152
|
+
# unfreeze 'options' && set defaults (:tla_dir)
|
153
|
+
setOptions( setup )
|
154
|
+
|
155
|
+
# Default FILE vs. given on cmd line
|
156
|
+
file = traceFile( setup, file )
|
157
|
+
|
158
|
+
template = "{{>#{ADD_LINKS_TEMPLATE}}}"
|
159
|
+
# no_strings = true && !options[:embed]
|
160
|
+
|
161
|
+
# read 'file' yielding String/Hash and parsedLines producing Hash
|
162
|
+
processInput( file ) do |data,parsedLines|
|
163
|
+
if data.is_a?(String)
|
164
|
+
# Not parseable line
|
165
|
+
puts data if options[:embed]
|
166
|
+
elsif data.is_a?(Hash)
|
167
|
+
# template = "{{>add-links}}" or {{>api-calls}}
|
168
|
+
rendered = rendering.render(template, data)
|
169
|
+
puts rendered if rendered.length > 0
|
170
|
+
|
171
|
+
# output parsedLines - producing 'data'
|
172
|
+
puts parsedLines.join( "" ) if options[:embed]
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end # add_links
|
179
|
+
|
180
|
+
desc "api-calls SETUP [FILE]", "Create API calls tla+tools trace ouput in FILE (- for STDIN) for SETUP"
|
181
|
+
long_desc <<-EOF
|
182
|
+
|
183
|
+
Create API calls using tla+tools trace output FILE (default 'gen/tlc.out').
|
184
|
+
|
185
|
+
API calls are resolved using 'interface.yaml' YAML file found in
|
186
|
+
specification code directory (option :tla-dir).
|
187
|
+
|
188
|
+
Use command
|
189
|
+
|
190
|
+
cat $(bundle show tla-trace-filter)/mustache/api-call-init.mustache
|
191
|
+
|
192
|
+
for instructions to map interface operations to mustache partials.
|
193
|
+
|
194
|
+
|
195
|
+
#{MUSTACHE_OPTION}
|
196
|
+
EOF
|
197
|
+
|
198
|
+
shared_options :mustache
|
199
|
+
shared_options :debug_mustache
|
200
|
+
shared_options :tla_dir
|
201
|
+
shared_options :src_dir
|
202
|
+
shared_options :state_dump
|
203
|
+
shared_options :filter_src
|
204
|
+
shared_options :solc_line
|
205
|
+
|
206
|
+
def api_calls( setup, file=nil)
|
207
|
+
|
208
|
+
# unfreeze 'options' && set defaults (:tla_dir)
|
209
|
+
setOptions( setup )
|
210
|
+
|
211
|
+
# Load fixed named template - allow used to define mapping
|
212
|
+
apiInitTemplate = "{{>#{API_CALL_INIT} }}"
|
213
|
+
@logger.info "#{__method__}, apiInitTemplate=#{apiInitTemplate}"
|
214
|
+
rendered = rendering.render(apiInitTemplate, options)
|
215
|
+
@logger.info "#{__method__}, output from init '#{rendered}'"
|
216
|
+
puts rendered if rendered.length > 0
|
217
|
+
|
218
|
+
# Default FILE vs. given on cmd line
|
219
|
+
file = traceFile( setup, file )
|
220
|
+
|
221
|
+
template = "{{>#{API_CALL_TEMPLATE} }}"
|
222
|
+
@logger.info "#{__method__}, template=#{template}"
|
223
|
+
|
224
|
+
# queue length of 1
|
225
|
+
q = nil
|
226
|
+
lastData = nil
|
227
|
+
|
228
|
+
# read 'file' yielding String/Hash and parsedLines producing Hash
|
229
|
+
processInput( file ) do |data, parsedLines|
|
230
|
+
|
231
|
+
if data.is_a?(String)
|
232
|
+
# api - call do not ouput trace lines
|
233
|
+
elsif data.is_a?(Hash)
|
234
|
+
|
235
|
+
# reason to output api-call
|
236
|
+
if data[:interface_started]
|
237
|
+
|
238
|
+
if q.nil?
|
239
|
+
# init qeueu
|
240
|
+
q = data
|
241
|
+
else
|
242
|
+
|
243
|
+
# output prev element in queue
|
244
|
+
q[:inputState] = q[:parsed][:state_space]
|
245
|
+
q[:now] = q[:parsed][:state_space][:now]
|
246
|
+
q[:outputState] = lastData[:parsed][:state_space]
|
247
|
+
# render parsed data && output if any ouput
|
248
|
+
rendered = rendering.render(template, q)
|
249
|
+
puts rendered if rendered.length > 0
|
250
|
+
|
251
|
+
# queue current data
|
252
|
+
q = data
|
253
|
+
end
|
254
|
+
|
255
|
+
end # interface_started
|
256
|
+
|
257
|
+
# rememeber it
|
258
|
+
lastData = data
|
259
|
+
|
260
|
+
end # elsif Hash?
|
261
|
+
end # block
|
262
|
+
|
263
|
+
if !q.nil?
|
264
|
+
# render parsed data && output if any ouput
|
265
|
+
q[:inputState] = q[:parsed][:state_space]
|
266
|
+
q[:now] = q[:parsed][:state_space][:now]
|
267
|
+
q[:outputState] = lastData[:parsed][:state_space]
|
268
|
+
rendered = rendering.render(template, q)
|
269
|
+
puts rendered if rendered.length > 0
|
270
|
+
|
271
|
+
end #
|
272
|
+
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
# @!endgroup
|
278
|
+
|
279
|
+
|
280
|
+
# ------------------------------------------------------------------
|
281
|
+
# @!group No commans
|
282
|
+
|
283
|
+
no_commands do
|
284
|
+
|
285
|
+
# @param parsed [Hash] parsed model checking state
|
286
|
+
#
|
287
|
+
# @param interfaceDefintion [type] interface for currently
|
288
|
+
# running prorcess
|
289
|
+
#
|
290
|
+
# @param stepStarted [Boolean] true/false
|
291
|
+
#
|
292
|
+
# @param options [Hash] command line options to cli
|
293
|
+
#
|
294
|
+
#
|
295
|
+
# @return [Hash] data with properties :options, :parsed,
|
296
|
+
# :interface_started, :interface_executing, :interface,
|
297
|
+
# :pc, :interface_opeation
|
298
|
+
def dataHash( parsed, stepStarted, interfaceDefintion, options )
|
299
|
+
|
300
|
+
data = {
|
301
|
+
:options => options, # from command line
|
302
|
+
:parsed => parsed, # from filter.rb: :line, :actionLine, :state_space
|
303
|
+
|
304
|
+
# true/false = state_space[:step] ~ :interface_operation
|
305
|
+
:interface_started => stepStarted, # interfaceStarted?( interfaceDefintion[:interface_operation], parsed[:state_space] ),
|
306
|
+
:interface_executing => !stepStarted, #interfaceExecuting?( interfaceDefintion[:interface_operation], parsed[:state_space] ),
|
307
|
+
:interface => setInterfaceDefaults( getStep(parsed), interfaceDefintion ), # from interfaces.yaml
|
308
|
+
:pc => interfacePc( interfaceDefintion[:interface_operation], parsed[:state_space] ),
|
309
|
+
:interface_operation => interfaceOperation( interfaceDefintion[:interface_operation], parsed[:state_space] ),
|
310
|
+
# :tst => ->( xx) { raise "tst #{xx}" },
|
311
|
+
}
|
312
|
+
@logger.debug "#{__method__}: data = #{data.to_yaml}" if @logger.debug?
|
313
|
+
|
314
|
+
data
|
315
|
+
end
|
316
|
+
|
317
|
+
# Process 'file', yield result
|
318
|
+
#
|
319
|
+
# @yields [String|Hash,Array<String>] data, parsedLines
|
320
|
+
def processInput( file )
|
321
|
+
|
322
|
+
# toggle when step changes
|
323
|
+
currStep = nil
|
324
|
+
currTick = nil
|
325
|
+
|
326
|
+
filterInput( file ) do |output|
|
327
|
+
|
328
|
+
# If string or a hash
|
329
|
+
|
330
|
+
if output.is_a?( String)
|
331
|
+
# No change - or line changed in place
|
332
|
+
yield output, []
|
333
|
+
elsif output.is_a?(Hash)
|
334
|
+
step = getStep( output[:state_space])
|
335
|
+
tick = getTick( output[:state_space] )
|
336
|
+
stepStarted = if currStep != step || currTick != tick then
|
337
|
+
currStep = step
|
338
|
+
currTick = tick
|
339
|
+
true
|
340
|
+
else
|
341
|
+
false
|
342
|
+
end
|
343
|
+
@logger.info "#{__method__}: step=#{step}, stepStarted=#{stepStarted}"
|
344
|
+
|
345
|
+
# Lookup in 'interfaces.yaml' for 'output[:state_space][:step]'
|
346
|
+
interfaceDefintion = getInterfaceDefinition(step, output[:state_space])
|
347
|
+
# data rendered: see mustache add-links.mustache and api-calls.mustache
|
348
|
+
data = dataHash( output, stepStarted, interfaceDefintion, options, )
|
349
|
+
@logger.info "#{__method__}: interface_started=#{data[:interface_started]}, interface_executing=#{data[:interface_executing]}"
|
350
|
+
|
351
|
+
yield data, filtering.lines
|
352
|
+
# # template = "{{>add-links}}" or {{>api-calls}}
|
353
|
+
# rendered = rendering.render(template, data)
|
354
|
+
# puts rendered if rendered.length > 0
|
355
|
+
# # Output original lines?
|
356
|
+
# puts filtering.lines.join( "" ) unless no_strings
|
357
|
+
else
|
358
|
+
raise "Unknown output.type #{output.class} for #{output}"
|
359
|
+
end
|
360
|
+
end # block for filterInput
|
361
|
+
|
362
|
+
end # processInput
|
363
|
+
|
364
|
+
# Read input lines from file/stdin, filter these lines and yield
|
365
|
+
# filtered result
|
366
|
+
#
|
367
|
+
# @yield [String|Hash] filtered result where String is input
|
368
|
+
# line (on line processed in place), Hash in parsed state
|
369
|
+
# space
|
370
|
+
def filterInput( file )
|
371
|
+
input = if file != "-" then
|
372
|
+
raise "Non existing file '#{file}'" unless File.exists?(file)
|
373
|
+
File.open( file )
|
374
|
+
else
|
375
|
+
STDIN
|
376
|
+
end
|
377
|
+
@logger.info "#{__method__}: starting, options=#{options}"
|
378
|
+
# $stdin.each_line do |line|
|
379
|
+
input.each_line do |line|
|
380
|
+
@logger.debug "#{__method__}: read line #{line}" if @logger.debug?
|
381
|
+
filtered = filtering.filter(line)
|
382
|
+
@logger.debug "#{__method__}: filtered filtered=#{filtered}" if @logger.debug?
|
383
|
+
if !filtered.nil?
|
384
|
+
yield filtered
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
end
|
389
|
+
|
390
|
+
# Implementation reads an array of interfaces from file
|
391
|
+
# 'interfaces.yaml' and converts it to a hash map
|
392
|
+
# interface[:interface_name] => interface read using
|
393
|
+
# "interfaces.yaml" file in 'tlaPath'.
|
394
|
+
#
|
395
|
+
# @return [Hash, {}] cached 'tlaPath/interfaces.yaml' file,
|
396
|
+
# empty hash if :step not defined (for initial step)
|
397
|
+
|
398
|
+
def getInterfaces( tlaPath )
|
399
|
+
return @interfaces if @interfaces
|
400
|
+
@logger.info "#{__method__}: tlaPath=#{tlaPath}"
|
401
|
+
@interfaces =
|
402
|
+
YAML.load_file( File.join( tlaPath, "interfaces.yaml")).inject( {}) do |memo,interface|
|
403
|
+
memo[interface[:interface_name]] = interface
|
404
|
+
memo
|
405
|
+
end || {}
|
406
|
+
@logger.info( "#{__method__}: @interfaces.keys=#{@interfaces.keys.join(',')}")
|
407
|
+
@logger.debug( "#{__method__}: @interfaces=#{@interfaces.to_yaml}") if @logger.debug?
|
408
|
+
@interfaces
|
409
|
+
end
|
410
|
+
|
411
|
+
# @param step [String] step exectuting
|
412
|
+
#
|
413
|
+
#
|
414
|
+
# @param stateSpace [Hash] hash containing state space dump from
|
415
|
+
# trace file, particularly it defines property :step,
|
416
|
+
# which is used as key to a hash from 'interfaces.yaml'.
|
417
|
+
#
|
418
|
+
# @return [Hash] definition of the interface
|
419
|
+
def getInterfaceDefinition( step, stateSpace )
|
420
|
+
|
421
|
+
@logger.debug "#{__method__}: stateSpace=#{stateSpace}" if @logger.debug?
|
422
|
+
# eg. p__customer_post_
|
423
|
+
return {} if step.nil?
|
424
|
+
|
425
|
+
# e.g. _customer_post_
|
426
|
+
interfaceName = step2InterfaceName(step)
|
427
|
+
@logger.info "#{__method__}: interfaceName=#{interfaceName}"
|
428
|
+
|
429
|
+
# expect 'interfaceName' to be defined in 'interfaces.yaml'
|
430
|
+
interfaceHash = getInterfaces(options[:tla_dir])[interfaceName] || {}
|
431
|
+
@logger.info "#{__method__}: interfaceName=#{interfaceName} -> interfaceHash=#{interfaceHash.to_yaml}"
|
432
|
+
|
433
|
+
interfaceHash
|
434
|
+
end
|
435
|
+
|
436
|
+
# # @param interface_operation [String] interface geth(mine)
|
437
|
+
# # executing tla transition parsed in state space
|
438
|
+
# #
|
439
|
+
# # @param state_space [Hash] state space state parsed
|
440
|
+
# #
|
441
|
+
# # @return [Boolean] true if
|
442
|
+
# # state_space[:pc][interface_operation] ends_with
|
443
|
+
# # '_start', edge case return 'false' if
|
444
|
+
# # 'interface_operation' not found in 'state_space'
|
445
|
+
# #
|
446
|
+
|
447
|
+
# def interfaceStarted?(interface_operation, state_space)
|
448
|
+
# @logger.debug "#{__method__}: interface_operation, state_space=#{state_space.to_yaml}" if @logger.debug?
|
449
|
+
# @logger.info "#{__method__}: look '#{interface_operation}' in #{state_space[:pc]}"
|
450
|
+
# return false if interface_operation.nil? || interface_operation.length == 0
|
451
|
+
# return false if state_space[:pc][interface_operation].nil?
|
452
|
+
# # state_space[:pc][interface_operation].end_with? "_start"
|
453
|
+
# isStart?( state_space[:pc][interface_operation] )
|
454
|
+
# end
|
455
|
+
|
456
|
+
# # @param interface_operation [String] interface geth(mine)
|
457
|
+
# # executing tla transition parsed in state space
|
458
|
+
# #
|
459
|
+
# # @param state_space [Hash] state space state parsed
|
460
|
+
# #
|
461
|
+
# # @return [Boolean] true if
|
462
|
+
# # state_space[:pc][interface_operation] does NOT ends
|
463
|
+
# # '_start' && 'interface_operation' found in 'state_space'
|
464
|
+
# #
|
465
|
+
|
466
|
+
# def interfaceExecuting?(interface_operation, state_space)
|
467
|
+
# # not valid interface_operation
|
468
|
+
# return false if interface_operation.nil? || interface_operation.length == 0
|
469
|
+
# return false if state_space[:pc][interface_operation].nil?
|
470
|
+
# # toggle isStart?
|
471
|
+
# return !isStart?( state_space[:pc][interface_operation] )
|
472
|
+
# end
|
473
|
+
|
474
|
+
# @param interface_operation [String] interface geth(mine)
|
475
|
+
# executing tla transition parsed in state space
|
476
|
+
#
|
477
|
+
# @param state_space [Hash] state space state parsed
|
478
|
+
#
|
479
|
+
#
|
480
|
+
# @return [String] state_space[pc][:step] of ??? if not possible
|
481
|
+
# to find
|
482
|
+
def interfacePc(interface_operation, state_space)
|
483
|
+
return "??" if interface_operation.nil? || interface_operation.length == 0
|
484
|
+
return "??" if state_space[:pc][interface_operation].nil?
|
485
|
+
state_space[:pc][interface_operation]
|
486
|
+
end
|
487
|
+
|
488
|
+
# @param interface_operation [String] interface geth(mine)
|
489
|
+
# executing tla transition parsed in state space
|
490
|
+
#
|
491
|
+
# @param state_space [Hash] state space state parsed
|
492
|
+
#
|
493
|
+
#
|
494
|
+
# @return [String] interface_operation, ??? if not possible to
|
495
|
+
# find
|
496
|
+
def interfaceOperation( interface_operation, state_space)
|
497
|
+
return "??" if interface_operation.nil? || interface_operation.length == 0
|
498
|
+
interface_operation
|
499
|
+
end
|
500
|
+
|
501
|
+
# def isStart?( interfaceOperation )
|
502
|
+
# @logger.info "#{__method__}: interfaceOperation=#{interfaceOperation}"
|
503
|
+
# return interfaceOperation.end_with? "_start"
|
504
|
+
# end
|
505
|
+
|
506
|
+
# @return [String] file, 'gen/<setup>/tlc.out' if file.nil?
|
507
|
+
def traceFile(setup, file)
|
508
|
+
file.nil? ? "gen/#{setup}/tlc.out" : file
|
509
|
+
end
|
510
|
+
|
511
|
+
# unfreeze 'options' && set defaults (:tla_dir)
|
512
|
+
def setOptions( setup )
|
513
|
+
# unfreeze options
|
514
|
+
new_options = options.dup
|
515
|
+
self.options = new_options
|
516
|
+
|
517
|
+
# use default :tla_dir - unless given on cmd_line
|
518
|
+
options.merge!( :tla_dir => "gen/#{setup}/tla") if options[:tla_dir].nil?
|
519
|
+
|
520
|
+
end
|
521
|
+
|
522
|
+
# @return [String] state space variable :step, which defines
|
523
|
+
# sbuilder interface invoked by sbuilder environment
|
524
|
+
# schedulr
|
525
|
+
def getStep( stateSpace)
|
526
|
+
stateSpace[:step]
|
527
|
+
end
|
528
|
+
|
529
|
+
|
530
|
+
# @return [String] step time tick
|
531
|
+
def getTick( stateSpace)
|
532
|
+
stateSpace[:now]
|
533
|
+
end
|
534
|
+
|
535
|
+
|
536
|
+
# Set defaults to interface definition to allow filtering to
|
537
|
+
# proceed
|
538
|
+
#
|
539
|
+
# @param step [String] Step, which parsed from state space dump
|
540
|
+
#
|
541
|
+
# @return [Hash] hash with :sourceModule guaranteed to exist
|
542
|
+
def setInterfaceDefaults( step, interfaceHash )
|
543
|
+
|
544
|
+
interfaceHash[:interface_operation] ||= step || "** unidentified step ** "
|
545
|
+
interfaceHash[:source] ||= { }
|
546
|
+
interfaceHash[:source][:sourceModule] ||= false
|
547
|
+
interfaceHash[:source][:interface_operation] ||= "**undefined**"
|
548
|
+
interfaceHash
|
549
|
+
end
|
550
|
+
|
551
|
+
# @return [String] substring '_name' from 'p__name'
|
552
|
+
def step2InterfaceName(step)
|
553
|
+
step[2..-1]
|
554
|
+
end
|
555
|
+
|
556
|
+
end # no_command
|
557
|
+
|
558
|
+
# @!endgroup no commans
|
559
|
+
|
560
|
+
|
561
|
+
|
562
|
+
end
|
563
|
+
end
|