tla-trace-filter 0.0.3 → 0.0.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2804fbc967c6c2816038bd6f3b6a8cfee973484
4
- data.tar.gz: 9fab9d64242a596da309fa119ef34401f608cc7b
3
+ metadata.gz: c26773e9c1c8523333a24665eb9f648f021b17a0
4
+ data.tar.gz: d5a1a47884bb9bb5b07eede01df7e567037b7e57
5
5
  SHA512:
6
- metadata.gz: 400432361333e1f8c3186c9ea77907877c1fc09ea7ee01c994f1b29d0f31ac15a39a5867422541c29dec1c4258136c700eb5d40072ee5ac9f8ff0437b7e9fd3c
7
- data.tar.gz: 30366f9fade7597713f53e02d62bad8e37449ce5b0f249ddd87039191fc5562ccbd677ffb2bc211ed3f69e9b41ad4f9da145fca83ece7810cd659d14df5ae659
6
+ metadata.gz: c47bd7b02c21164670b48fee9f5ede938c80e25673bb17864e1a25bd31b75296c54c6b7d72aaf667c0d079ac51b23879bafc3011ad8f8f1b06d70f80bc670855
7
+ data.tar.gz: 40ef12b948cf1b57fccd9a700bec5561a2ae33813c03a633d7f867c15718292c1214b18032e9ebdcff05fc5cbe9d1ffbe1f37083bd50d22f806efbcdf66b7ddd
@@ -0,0 +1,108 @@
1
+ # `tla-sbuilder-trace` - Post process trace output from model checking sbuilder formal models
2
+
3
+ Command line filter for
4
+ processing
5
+ [TLA+ Tools](http://research.microsoft.com/en-us/um/people/lamport/tla/tools.html) trace
6
+ output resulting from model
7
+ checking
8
+ [TLA+ language](http://research.microsoft.com/en-us/um/people/lamport/tla/book.html) specification
9
+ code generated
10
+ using [sbuilder](https://github.com/jarjuk/tla-sbuilder) -tool.
11
+
12
+ The tool implements two commands
13
+
14
+ * `add-links` : for adding links pointing 1) to *TLA+ language*
15
+ specification code and 2) to source code translated by sbuilder tool
16
+
17
+ * `api-calls` : for interpreting transitions in trace output as
18
+ interface calls on sbuilder source code translated by *sbuilder* tool
19
+
20
+
21
+ ## Installation
22
+
23
+
24
+ To install `tla-trace-filter` GEM create a `Gemfile` -file with the
25
+ content
26
+
27
+ ```
28
+ source "https://rubygems.org"
29
+ gem 'tla-trace-filter'
30
+ ```
31
+
32
+ and run
33
+
34
+ bundle install
35
+
36
+
37
+ ## Usage
38
+
39
+ ### tla-trace-filter.rb add-links
40
+
41
+ To add links to model checker trace output in file `gen/tlc.out`
42
+ resulting from model checking *TLA+ language* specification code in
43
+ file `gen/setup1/tla/model.tla`, and using YAML file
44
+ `gen/setup1/tla/interfaces.yaml` to map transition names back to
45
+ source code modules in directory `solidity` run:
46
+
47
+ bundle exec tla-trace-filter.rb add-links setup1
48
+
49
+
50
+ To embed links to trace output run:
51
+
52
+ bundle exec tla-trace-filter.rb add-links setup1 --embed
53
+
54
+
55
+ ### tla-trace-filter.rb api-calls
56
+
57
+ To create API calls run:
58
+
59
+ bundle exec tla-trace-filter.rb api-calls setup1
60
+
61
+
62
+ ### Getting help
63
+
64
+ Location of the files and directories can be changes using command
65
+ line options. To get a list of available command and their options
66
+ run:
67
+
68
+ bundle exec tla-trace-filter.rb help
69
+
70
+ ## Documentation
71
+
72
+ See [Cucumber](https://cucumber.io/) tests in GEM directory `features`.
73
+
74
+ For a demonstration of `api-call-init` -extension point refer to
75
+ a
76
+ [blog entry](https://jarjuk.wordpress.com/2017/12/06/sbuilder-wallet-3/).
77
+
78
+
79
+ ## <a id="API-CALL_INIT">`api-call-init`-extension point</a>
80
+
81
+ `tla-trace-filter.rb` -tool
82
+ uses [mustache](https://mustache.github.io/) templates to produce
83
+ output. Default templates used are located in GEM directory
84
+ `mustache`. Command line option `--mustache` can override the
85
+ location, where templates are searched for.
86
+
87
+ To show templates, used by the tool, issue the command
88
+
89
+ ls $(bundle show tla-trace-filter)/mustache
90
+
91
+ To get instructions, how to use `api-call-init` -extension point,
92
+ issue the command:
93
+
94
+ cat $(bundle show tla-trace-filter)/mustache/api-call-init.mustache
95
+
96
+
97
+ ## <a id="MUSTACHE-LAMBDAS">Mustache output lambdas</a>
98
+
99
+ Following lambda function are available in mustache template
100
+
101
+ * `{{#YAML_DUMP}}key{{/YAML_DUMP}}` : dump context `key` as YAML,
102
+ e.g. to dump `beforeState`, `api_input`, `api_return` or
103
+ `afterState` for `tla-trace-filter.rb api-calls` -command
104
+
105
+
106
+ ## License
107
+
108
+ MIT
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.6
@@ -2,6 +2,8 @@ require_relative "../tla-trace-filter.rb"
2
2
 
3
3
  require 'thor'
4
4
  require 'yaml'
5
+ require 'socket' # gethostname
6
+ require 'digest' # sha1
5
7
 
6
8
  module TlaTraceFilter
7
9
  class Cli < Thor
@@ -12,13 +14,16 @@ module TlaTraceFilter
12
14
  API_CALL_TEMPLATE = "api-call" # root template for command 'api-call'
13
15
  ADD_LINKS_TEMPLATE = "add-links" # root template for command 'add-links'
14
16
 
17
+ API_CALL_PRE = "api-call-pre" # render before anything other templates
18
+ API_CALL_POST = "api-call-post" # render last
19
+
15
20
 
16
21
 
17
22
  VERSION_BANNER = <<~EOS
18
23
  #{File.basename $0}: #{File.readlines( File.join File.dirname( __FILE__ ), "../../VERSION" ).first.gsub( /\n/, "" )}
19
24
  EOS
20
25
 
21
- MUSTACHE_DEFAULT = "mustache/"
26
+ MUSTACHE_DEFAULT = [ "mustache/" ]
22
27
  MUSTACHE_OPTION= <<-EOS
23
28
  Output is processed using mustache templates in directory
24
29
  #{File.dirname __FILE__}/../../mustache. Mustache templates can be
@@ -48,6 +53,9 @@ module TlaTraceFilter
48
53
  def rendering
49
54
  @rendering ||= TlaTraceFilter::Render.new( options )
50
55
  end
56
+
57
+ # @# @!attribute [Digest:SHA1] sha1
58
+ attr_accessor :sha1
51
59
 
52
60
  end
53
61
 
@@ -106,10 +114,11 @@ module TlaTraceFilter
106
114
  add_shared_option :tla_dir, :type=>:string, :desc=>"Override default specification code dir gen/SETUP/tla"
107
115
  add_shared_option :src_dir, :default=>"./solidity", :type=>:string, :desc=>"Source code root directory"
108
116
  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
117
+ add_shared_option :mustache, :aliases => "-m", :type => :array, :desc => "Add a directory (ends with /-char) or GEM to search for mustache template", :default=> MUSTACHE_DEFAULT
110
118
  add_shared_option :solc_line, :type => :boolean, :default=>false, :desc => "TRUE interpretes sourceLines as characters starting from source start"
111
119
  add_shared_option :debug_mustache, :type => :boolean, :default=>false, :desc => "Raise exception if referencing non-existing property"
112
120
  add_shared_option :embed, :type => :boolean, :default=>false, :desc => "TRUE adds link to trace output"
121
+ add_shared_option :sha1, :type => :boolean, :default=>true, :desc => "Make :sha1 available for template #{API_CALL_POST}"
113
122
 
114
123
  # @!endgroup
115
124
 
@@ -185,11 +194,10 @@ module TlaTraceFilter
185
194
  API calls are resolved using 'interface.yaml' YAML file found in
186
195
  specification code directory (option :tla-dir).
187
196
 
188
- Use command
189
197
 
190
- cat $(bundle show tla-trace-filter)/mustache/api-call-init.mustache
191
-
192
- for instructions to map interface operations to mustache partials.
198
+ Extension points:
199
+ - cat $(bundle show tla-trace-filter)/mustache/api-call-init.mustache:
200
+ dynamic distpatch based on context[:interface][:interface_operation]
193
201
 
194
202
 
195
203
  #{MUSTACHE_OPTION}
@@ -202,18 +210,25 @@ module TlaTraceFilter
202
210
  shared_options :state_dump
203
211
  shared_options :filter_src
204
212
  shared_options :solc_line
213
+ shared_options :sha1
205
214
 
206
215
  def api_calls( setup, file=nil)
207
216
 
208
217
  # unfreeze 'options' && set defaults (:tla_dir)
209
218
  setOptions( setup )
210
219
 
220
+ # init sha1 calculation
221
+ sha1Init
222
+
211
223
  # Load fixed named template - allow used to define mapping
212
224
  apiInitTemplate = "{{>#{API_CALL_INIT} }}"
213
225
  @logger.info "#{__method__}, apiInitTemplate=#{apiInitTemplate}"
214
226
  rendered = rendering.render(apiInitTemplate, options)
215
227
  @logger.info "#{__method__}, output from init '#{rendered}'"
216
- puts rendered if rendered.length > 0
228
+ # outputRendered(rendered)
229
+
230
+ # preamble partial
231
+ outputRendered( rendering.render( "{{>#{API_CALL_PRE}}}", preAndPostHash(options ) ) )
217
232
 
218
233
  # Default FILE vs. given on cmd line
219
234
  file = traceFile( setup, file )
@@ -222,54 +237,71 @@ module TlaTraceFilter
222
237
  @logger.info "#{__method__}, template=#{template}"
223
238
 
224
239
  # queue length of 1
225
- q = nil
226
- lastData = nil
240
+ interfaceBeforeState = nil
241
+ interfaceEnterState = nil
242
+ interfaceEndState = nil
227
243
 
228
244
  # read 'file' yielding String/Hash and parsedLines producing Hash
229
245
  processInput( file ) do |data, parsedLines|
230
246
 
231
247
  if data.is_a?(String)
232
- # api - call do not ouput trace lines
248
+ # api - call do not output trace lines
233
249
  elsif data.is_a?(Hash)
234
250
 
235
251
  # reason to output api-call
236
252
  if data[:interface_started]
237
253
 
238
- if q.nil?
239
- # init qeueu
240
- q = data
254
+ if interfaceBeforeState.nil?
255
+ # first time processing state 0
256
+ interfaceBeforeState = data
257
+ @logger.debug "loop: init interfaceBeforeState: #{interfaceBeforeState}" if @logger.debug?
258
+ elsif interfaceEnterState.nil?
259
+ # state 0 has been processed - is this the first interface
260
+ interfaceEnterState = data
241
261
  else
242
262
 
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
263
+ # New iterface has started to execute. Now we can render
264
+ # apiStep for previous interface call using state collected in
265
+ #
266
+ # * beforeState: takens from 'interfaceBeforeState': it s either the first
267
+ # 'data' parsed OR 'data' parsed , which was reached
268
+ # after executing previous interface call.
269
+
270
+ # * afterState: taken from preceding 'data' in 'interfaceEndState'
271
+ apiOutput = canonizeData( interfaceBeforeState, interfaceEnterState, interfaceEndState )
272
+ @logger.debug "loop: apiOutput #{apiOutput}" if @logger.debug?
273
+ rendered = rendering.render(template, apiOutput)
274
+ outputRendered( rendered )
275
+
276
+ # init 'interfaceBeforeState' as 'interfaceEndState'
277
+ # from the previous step (which was just rendered)
278
+ interfaceBeforeState = interfaceEndState
279
+ # init 'interfaceEnterState' to current 'data' parsed from inputfile
280
+ interfaceEnterState = data
281
+ @logger.debug "loop: set interfaceBeforeState #{interfaceBeforeState}" if @logger.debug?
253
282
  end
254
283
 
255
284
  end # interface_started
256
285
 
257
- # rememeber it
258
- lastData = data
286
+ # advance 'interfaceEndState' with current 'data'
287
+ interfaceEndState = data
259
288
 
260
289
  end # elsif Hash?
261
290
  end # block
262
291
 
263
- if !q.nil?
292
+ # flush interfaceBeforeState
293
+ if !interfaceBeforeState.nil?
264
294
  # 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
295
+ apiOutput = canonizeData( interfaceBeforeState, interfaceEnterState || interfaceEndState, interfaceEndState )
296
+ @logger.debug "loop:exit: apiOutput (quit) #{apiOutput}" if @logger.debug?
297
+ rendered = rendering.render(template, apiOutput)
298
+ outputRendered( rendered )
270
299
 
271
300
  end #
272
-
301
+
302
+ # postamble (including setting sha1) - but not calculating it
303
+ rendered = rendering.render("{{>#{API_CALL_POST}}}", preAndPostHash(options ) )
304
+ puts rendered if rendered.length > 0
273
305
 
274
306
  end
275
307
 
@@ -278,10 +310,68 @@ module TlaTraceFilter
278
310
 
279
311
 
280
312
  # ------------------------------------------------------------------
281
- # @!group No commans
313
+ # @!group No commansd
282
314
 
283
315
  no_commands do
284
316
 
317
+ # INitialize sha1 opbject
318
+ def sha1Init
319
+ self.sha1 = Digest::SHA1.new if options[:sha1]
320
+ end
321
+
322
+ def sha1Update( data )
323
+ sha1.update( data ) if options[:sha1]
324
+ # @logger.debug "#{__method__}: lines=#{@lines}, sha1.hexdigest=#{sha1.hexdigest}, data=#{data}" if @logger.debug?
325
+ end
326
+
327
+
328
+ # Output 'rendered' line && calculate sha1
329
+ def outputRendered rendered
330
+ if rendered.length > 0
331
+ sha1Update( rendered )
332
+ puts rendered
333
+ end
334
+ end
335
+
336
+ # @return [Hash] data hash passed to pre/post templates.
337
+ def preAndPostHash( options)
338
+ {
339
+ :options => options,
340
+ :META => getMeta(),
341
+ :sha1 => sha1,
342
+ }
343
+ end
344
+
345
+ def getMeta
346
+ {
347
+ :timestamp => Time.new.strftime( "%Y-%m-%d %H:%M:%S" ),
348
+ :hostname => Socket.gethostname,
349
+ :user => ENV["USER"],
350
+ }
351
+ end
352
+
353
+ # @return [Hash] with properties from
354
+ # 'interfaceBeforeState','interfaceEnterState' and
355
+ # 'interfaceEndState'
356
+ def canonizeData( interfaceBeforeState, interfaceEnterState, interfaceEndState )
357
+ ret = {
358
+ options: interfaceBeforeState[:options], # cmd line options
359
+ interface_started: true,
360
+ beforeState: interfaceBeforeState[:parsed][:state_space],
361
+ parsed: interfaceEnterState[:parsed],
362
+ now: interfaceEndState[:parsed][:state_space][:now],
363
+ interface: interfaceEndState[:interface],
364
+ interface_operation: interfaceEndState[:interface_operation],
365
+ afterState: interfaceEndState[:parsed][:state_space],
366
+ }
367
+
368
+ # q[:beforeState] = q[:parsed][:state_space]
369
+ # q[:now] = lastData[:parsed][:state_space][:now]
370
+ # q[:interface] = lastData[:interface]
371
+ # q[:afterState] = lastData[:parsed][:state_space]
372
+ # q
373
+ end
374
+
285
375
  # @param parsed [Hash] parsed model checking state
286
376
  #
287
377
  # @param interfaceDefintion [type] interface for currently
@@ -433,43 +523,6 @@ module TlaTraceFilter
433
523
  interfaceHash
434
524
  end
435
525
 
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
526
 
474
527
  # @param interface_operation [String] interface geth(mine)
475
528
  # executing tla transition parsed in state space
@@ -510,6 +563,7 @@ module TlaTraceFilter
510
563
 
511
564
  # unfreeze 'options' && set defaults (:tla_dir)
512
565
  def setOptions( setup )
566
+ @logger.info "#{__method__}, options=#{options.to_yaml}"
513
567
  # unfreeze options
514
568
  new_options = options.dup
515
569
  self.options = new_options
@@ -15,11 +15,11 @@ module TlaTraceFilter
15
15
  # ------------------------------------------------------------------
16
16
  # @!group Constants
17
17
 
18
- # Default templates for inputState, call, and outputState
19
- API_INPUT_STATE_DEFAULT_PARTIAL = "api-call-input"
20
- API_CALL_DEFAULT_PARTIAL = "api-call-default"
21
- API_RETURN_DEFAULT_PARTIAL = "api-call-return"
22
- API_OUTPUT_STATE_DEFAULT_PARTIAL = "api-call-output"
18
+ # Default templates for beforeState, call, and afterState
19
+ API_BEFORE_STATE_DEFAULT_PARTIAL = "api-call-default-beforeState"
20
+ API_CALL_DEFAULT_PARTIAL = "api-call-default-api_input"
21
+ API_RETURN_DEFAULT_PARTIAL = "api-call-default-api_return"
22
+ API_AFTER_STATE_DEFAULT_PARTIAL = "api-call-default-afterState"
23
23
 
24
24
  # Keys mapping to the output templates
25
25
  API_DEFAULT_KEY = "default"
@@ -46,13 +46,13 @@ module TlaTraceFilter
46
46
  # (with default) to partial name
47
47
  attr_accessor :returnPartials
48
48
 
49
- # @# @!attribute [Hash] inputStatePartials hash mapping interface-names
49
+ # @# @!attribute [Hash] beforeStatePartials hash mapping interface-names
50
50
  # (with default) to partial name
51
- attr_accessor :inputStatePartials
51
+ attr_accessor :beforeStatePartials
52
52
 
53
- # @# @!attribute [Hash] outputStatePartials hash mapping interface-names
53
+ # @# @!attribute [Hash] afterStatePartials hash mapping interface-names
54
54
  # (with default) to partial name
55
- attr_accessor :outputStatePartials
55
+ attr_accessor :afterStatePartials
56
56
 
57
57
  # @!endgroup
58
58
 
@@ -79,18 +79,18 @@ module TlaTraceFilter
79
79
  # default search only GEM templates
80
80
  self.templatePaths = [ File.join( File.dirname(__FILE__), "../../mustache/") ]
81
81
  # user defined template search path prepended
82
- self.templatePaths = [ options[:mustache] ] + templatePaths if options[:mustache]
82
+ self.templatePaths = options[:mustache] + templatePaths if options[:mustache]
83
83
  end
84
84
 
85
85
  def initPartials
86
86
  self.partials = {}
87
87
  API_CALL_INIT( "" )
88
88
  API_RETURN_INIT( "" )
89
- API_INPUT_STATE_INIT( "" )
90
- API_OUTPUT_STATE_INIT( "" )
89
+ API_BEFORE_STATE_INIT( "" )
90
+ API_AFTER_STATE_INIT( "" )
91
91
  # self.callPartials = {}
92
- # self.inputStatePartials = {}
93
- # self.outputStatePartials = {}
92
+ # self.beforeStatePartials = {}
93
+ # self.afterStatePartials = {}
94
94
  end
95
95
 
96
96
  # @!endgroup
@@ -154,15 +154,15 @@ module TlaTraceFilter
154
154
 
155
155
  # Initiliaze template calls. If no data given results calling to
156
156
  # default templates
157
- def API_INPUT_STATE_INIT( data)
157
+ def API_BEFORE_STATE_INIT( data)
158
158
  @logger.info "#{__method__}: data=#{data}"
159
159
  begin
160
- self.inputStatePartials = data.nil? || data == "" ? {} : YAML.load( data )
160
+ self.beforeStatePartials = data.nil? || data == "" ? {} : YAML.load( data )
161
161
  rescue Exception => e
162
162
  msg = <<-EOS
163
163
  #{e}
164
164
 
165
- Error parsing YAML data in API_INPUT_STATE_INIT:
165
+ Error parsing YAML data in API_BEFORE_STATE_INIT:
166
166
 
167
167
  #{data}
168
168
  EOS
@@ -170,20 +170,20 @@ module TlaTraceFilter
170
170
  raise Exception.new, msg, e.backtrace
171
171
  end
172
172
 
173
- @logger.debug "#{__method__}: inputStatePartials=#{inputStatePartials}" if @logger.debug?
173
+ @logger.debug "#{__method__}: beforeStatePartials=#{beforeStatePartials}" if @logger.debug?
174
174
 
175
175
  # ensure that 'default' and 'empty' partials are defined
176
- self.inputStatePartials[API_DEFAULT_KEY] = API_INPUT_STATE_DEFAULT_PARTIAL if inputStatePartials[API_DEFAULT_KEY].nil?
177
- self.inputStatePartials[API_EMPTY_KEY] = API_OUTPUT_STATE_DEFAULT_PARTIAL if inputStatePartials[API_EMPTY_KEY].nil?
176
+ self.beforeStatePartials[API_DEFAULT_KEY] = API_BEFORE_STATE_DEFAULT_PARTIAL if beforeStatePartials[API_DEFAULT_KEY].nil?
177
+ self.beforeStatePartials[API_EMPTY_KEY] = API_AFTER_STATE_DEFAULT_PARTIAL if beforeStatePartials[API_EMPTY_KEY].nil?
178
178
 
179
179
  end
180
180
 
181
181
  # Lambda to initiliaze template calls. If no data given results
182
182
  # calling to default templates
183
- def API_OUTPUT_STATE_INIT( data)
183
+ def API_AFTER_STATE_INIT( data)
184
184
  @logger.info "#{__method__}: data=#{data}"
185
185
  begin
186
- self.outputStatePartials = data.nil? || data == "" ? {} : YAML.load( data )
186
+ self.afterStatePartials = data.nil? || data == "" ? {} : YAML.load( data )
187
187
  rescue Exception => e
188
188
  msg = <<-EOS
189
189
  #{e}
@@ -196,11 +196,11 @@ module TlaTraceFilter
196
196
  raise Exception.new, msg, e.backtrace
197
197
  end
198
198
 
199
- @logger.debug "#{__method__}: outputStatePartials=#{outputStatePartials}" if @logger.debug?
199
+ @logger.debug "#{__method__}: afterStatePartials=#{afterStatePartials}" if @logger.debug?
200
200
 
201
201
  # ensure that 'default' and 'empty' partials are defined
202
- self.outputStatePartials[API_DEFAULT_KEY] = API_OUTPUT_STATE_DEFAULT_PARTIAL if outputStatePartials[API_DEFAULT_KEY].nil?
203
- self.outputStatePartials[API_EMPTY_KEY] = API_OUTPUT_STATE_DEFAULT_PARTIAL if outputStatePartials[API_EMPTY_KEY].nil?
202
+ self.afterStatePartials[API_DEFAULT_KEY] = API_AFTER_STATE_DEFAULT_PARTIAL if afterStatePartials[API_DEFAULT_KEY].nil?
203
+ self.afterStatePartials[API_EMPTY_KEY] = API_AFTER_STATE_DEFAULT_PARTIAL if afterStatePartials[API_EMPTY_KEY].nil?
204
204
 
205
205
  end
206
206
 
@@ -236,25 +236,25 @@ module TlaTraceFilter
236
236
  end
237
237
 
238
238
  def getInputStatePartialName( interfaceOperation )
239
- inputStatePartialName = nil
240
- inputStatePartialName = inputStatePartials[API_EMPTY_KEY] if interfaceOperation.nil?
241
- inputStatePartialName = inputStatePartials[interfaceOperation] if inputStatePartialName.nil?
242
- inputStatePartialName = inputStatePartials[API_DEFAULT_KEY] if inputStatePartialName.nil?
243
- raise "Missing could not resolve '#{interfaceOperation}' in inputStatePartials #{inputStatePartials}" if inputStatePartialName.nil?
244
-
245
- @logger.info "#{__method__}: API-call to interfaceOperation '#{interfaceOperation}' render with '#{inputStatePartialName}'"
246
- inputStatePartialName
239
+ beforeStatePartialName = nil
240
+ beforeStatePartialName = beforeStatePartials[API_EMPTY_KEY] if interfaceOperation.nil?
241
+ beforeStatePartialName = beforeStatePartials[interfaceOperation] if beforeStatePartialName.nil?
242
+ beforeStatePartialName = beforeStatePartials[API_DEFAULT_KEY] if beforeStatePartialName.nil?
243
+ raise "Missing could not resolve '#{interfaceOperation}' in beforeStatePartials #{beforeStatePartials}" if beforeStatePartialName.nil?
244
+
245
+ @logger.info "#{__method__}: API-call to interfaceOperation '#{interfaceOperation}' render with '#{beforeStatePartialName}'"
246
+ beforeStatePartialName
247
247
  end
248
248
 
249
249
  def getOutputStatePartialName( interfaceOperation )
250
- outputStatePartialName = nil
251
- outputStatePartialName = outputStatePartials[API_EMPTY_KEY] if interfaceOperation.nil?
252
- outputStatePartialName = outputStatePartials[interfaceOperation] if outputStatePartialName.nil?
253
- outputStatePartialName = outputStatePartials[API_DEFAULT_KEY] if outputStatePartialName.nil?
254
- raise "Missing could not resolve '#{interfaceOperation}' in outputStatePartials #{outputStatePartials}" if outputStatePartialName.nil?
255
-
256
- @logger.info "#{__method__}: API-call to interfaceOperation '#{interfaceOperation}' render with '#{outputStatePartialName}'"
257
- outputStatePartialName
250
+ afterStatePartialName = nil
251
+ afterStatePartialName = afterStatePartials[API_EMPTY_KEY] if interfaceOperation.nil?
252
+ afterStatePartialName = afterStatePartials[interfaceOperation] if afterStatePartialName.nil?
253
+ afterStatePartialName = afterStatePartials[API_DEFAULT_KEY] if afterStatePartialName.nil?
254
+ raise "Missing could not resolve '#{interfaceOperation}' in afterStatePartials #{afterStatePartials}" if afterStatePartialName.nil?
255
+
256
+ @logger.info "#{__method__}: API-call to interfaceOperation '#{interfaceOperation}' render with '#{afterStatePartialName}'"
257
+ afterStatePartialName
258
258
  end
259
259
 
260
260
  # @!endgroup
@@ -297,18 +297,18 @@ module TlaTraceFilter
297
297
  lineCount
298
298
  end
299
299
 
300
- # Lamba called for 'API_INPUT_STATE' to dispatch dynamically rendering of
301
- # [:interface][:interface_operation] inputState.
302
- def API_INPUT_STATE
300
+ # Lamba called for 'API_BEFORE_STATE' to dispatch dynamically rendering of
301
+ # [:interface][:interface_operation] beforeState.
302
+ def API_BEFORE_STATE
303
303
  @logger.info "#{__method__}: [:interface][:interface_operation]=#{context[:interface][:interface_operation]}, now=#{context[:now]}"
304
304
  callPartialName = getInputStatePartialName( context[:interface][:interface_operation] )
305
305
  template = partial( callPartialName )
306
306
  render( template, context )
307
307
  end
308
308
 
309
- # Lamba called for 'API_OUTPUT_STATE' to dispatch dynamically rendering of
310
- # [:interface][:interface_operation] outputState.
311
- def API_OUTPUT_STATE
309
+ # Lamba called for 'API_AFTER_STATE' to dispatch dynamically rendering of
310
+ # [:interface][:interface_operation] afterState.
311
+ def API_AFTER_STATE
312
312
  @logger.info "#{__method__}: [:interface][:interface_operation]=#{context[:interface][:interface_operation]} now=#{context[:now]}"
313
313
  callPartialName = getOutputStatePartialName( context[:interface][:interface_operation] )
314
314
  template = partial( callPartialName )
@@ -316,6 +316,7 @@ module TlaTraceFilter
316
316
  end
317
317
 
318
318
  def API_RETURN
319
+ @logger.info "#{__method__}: [:interface][:interface_operation]=#{context[:interface][:interface_operation]} now=#{context[:now]}"
319
320
 
320
321
  interfaceOperation = context[:interface][:interface_operation]
321
322
  responseKey = context[:interface][:response_key]
@@ -325,8 +326,10 @@ module TlaTraceFilter
325
326
  template = partial( callPartialName )
326
327
 
327
328
  # context access likke i_Bank_saveAccount_
328
- # raise "keys=#{context[:outputState][:responses].to_yaml}"
329
- context[:api_return] = context[:outputState][:responses][responseKey]
329
+ # raise "keys=#{context[:afterState][:responses].to_yaml}"
330
+ @logger.debug "#{__method__}: context[:afterState]=#{context[:afterState].to_yaml}" if @logger.debug?
331
+
332
+ context[:api_return] = context[:afterState][:responses].nil? ? nil : context[:afterState][:responses][responseKey]
330
333
 
331
334
  render( template, context )
332
335
 
@@ -370,10 +373,10 @@ module TlaTraceFilter
370
373
  context[:parsed][:state_space][:step_input]
371
374
  else
372
375
 
373
- api = "#{context[:interface][:interface_name]}_input"
376
+ inputvariable = "#{context[:interface][:interface_name]}_input"
374
377
 
375
378
  # find name of procedure input varibable
376
- api = context[:parsed][:state_space].keys.find { |k| k.to_s.end_with?( api ) } unless api.nil?
379
+ api = context[:parsed][:state_space].keys.find { |k| k.to_s.end_with?( inputvariable) } unless inputvariable.nil?
377
380
 
378
381
  # access procedure input data
379
382
  api = context[:parsed][:state_space][api] unless api.nil?
@@ -381,7 +384,15 @@ module TlaTraceFilter
381
384
  # access procedure input for currently running interface opertaion
382
385
  api = api[context[:interface][:interface_operation]] unless api.nil?
383
386
 
384
- api = { :error => "No input found in context[:parsed][:state_space][:step_input] - maybe set 'SetStepInput = TRUE'"} if api.nil?
387
+ if api.nil?
388
+ msg = %Q{
389
+ No input found in context[:parsed][:state_space][:step_input] - maybe set 'SetStepInput = TRUE'
390
+
391
+ Tried to locate input variable ending with #{inputvariable} in context[:parsed][:state_space]
392
+ }
393
+
394
+ api = { :error => msg }
395
+ end
385
396
 
386
397
  api
387
398
  end
@@ -391,6 +402,26 @@ module TlaTraceFilter
391
402
  end
392
403
 
393
404
 
405
+ # @!endgroup
406
+
407
+ # # ------------------------------------------------------------------
408
+ # @!group DUmp
409
+
410
+ # dump 'contextKey' in in YAML, where 'contextKey' is path of hash
411
+ # keys repareated by '.'
412
+ def DUMP_YAML( contextKey )
413
+ # enable splitting key - just be sure
414
+ contextKey = contextKey.to_s unless contextKey.is_a? String
415
+ keys = contextKey.split(".")
416
+ c = context
417
+ keys.each do |key|
418
+ break if c.nil?
419
+ c = c[key.to_sym]
420
+ end
421
+ c.to_yaml
422
+ end
423
+
424
+
394
425
  # @!endgroup
395
426
 
396
427
 
@@ -494,7 +525,8 @@ module TlaTraceFilter
494
525
  # otherwiset (= also NOT even if installed locally in gems)
495
526
  def gem_location( gemName )
496
527
  gemSpec = Gem.loaded_specs[gemName]
497
- raise "Unknown gemName #{gemName}" if gemSpec.nil?
528
+ raise "Unknown gemName #{gemName} - known Gems #{Gem.loaded_specs.keys.join(",")} " if gemSpec.nil?
529
+ @logger.info "#{__method__}: gemName#{gemName} resolves to gemSpec.gem_dir#{gemSpec.gem_dir}"
498
530
  gemSpec.gem_dir
499
531
  end
500
532