origen_testers 0.5.7 → 0.6.0

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/config/shared_commands.rb +6 -0
  3. data/config/version.rb +2 -2
  4. data/lib/commands/run.rb +44 -0
  5. data/lib/origen_testers.rb +19 -1
  6. data/lib/origen_testers/flow.rb +382 -0
  7. data/lib/origen_testers/generator.rb +32 -29
  8. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -0
  9. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -0
  10. data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -0
  11. data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -0
  12. data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -0
  13. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +97 -0
  14. data/lib/origen_testers/igxl_based_tester/base/flow.rb +390 -115
  15. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +4 -54
  16. data/lib/origen_testers/igxl_based_tester/base/generator.rb +257 -11
  17. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -0
  18. data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -0
  19. data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -0
  20. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +109 -0
  21. data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -0
  22. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +33 -1
  23. data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -0
  24. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +47 -0
  25. data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +2 -2
  26. data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -0
  27. data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +4 -0
  28. data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -0
  29. data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -0
  30. data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -0
  31. data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -0
  32. data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -0
  33. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +137 -0
  34. data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -0
  35. data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -0
  36. data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -0
  37. data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -0
  38. data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -0
  39. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +58 -0
  40. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +58 -0
  41. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +95 -0
  42. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +2 -2
  43. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +121 -0
  44. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +24 -0
  45. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +137 -0
  46. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +4 -0
  47. data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -0
  48. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -0
  49. data/lib/origen_testers/interface.rb +41 -6
  50. data/lib/origen_testers/no_interface.rb +7 -0
  51. data/lib/origen_testers/origen_ext/application/runner.rb +25 -0
  52. data/lib/origen_testers/origen_ext/generator.rb +37 -0
  53. data/lib/origen_testers/origen_ext/generator/flow.rb +70 -0
  54. data/lib/origen_testers/origen_ext/generator/resources.rb +21 -0
  55. data/lib/origen_testers/program_generators.rb +0 -1
  56. data/lib/origen_testers/smartest_based_tester/base/flow.rb +158 -134
  57. data/lib/origen_testers/smartest_based_tester/base/generator.rb +2 -3
  58. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +4 -0
  59. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +5 -6
  60. data/lib/origen_testers/test/dut.rb +5 -0
  61. data/lib/origen_testers/test/j750_base_interface.rb +0 -3
  62. data/lib/origen_testers/test/ultraflex_interface.rb +230 -4
  63. data/lib/origen_testers/test/v93k_interface.rb +5 -23
  64. data/program/components/_temp.rb +6 -0
  65. data/program/flow_control.rb +190 -62
  66. data/program/prb1.rb +13 -50
  67. data/program/prb2.rb +0 -16
  68. data/program/test.rb +12 -3
  69. data/program/uflex_resources.rb +159 -0
  70. metadata +66 -16
  71. data/lib/origen_testers/doc.rb +0 -224
  72. data/lib/origen_testers/doc/generator.rb +0 -124
  73. data/lib/origen_testers/doc/generator/flow.rb +0 -69
  74. data/lib/origen_testers/doc/generator/flow_line.rb +0 -201
  75. data/lib/origen_testers/doc/generator/test.rb +0 -66
  76. data/lib/origen_testers/doc/generator/test_group.rb +0 -64
  77. data/lib/origen_testers/doc/generator/tests.rb +0 -45
  78. data/lib/origen_testers/doc/model.rb +0 -160
  79. data/lib/origen_testers/generator/flow_control_api.rb +0 -611
  80. data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +0 -476
  81. data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +0 -9
@@ -1,66 +0,0 @@
1
- module OrigenTesters
2
- class Doc
3
- module Generator
4
- class Test
5
- attr_accessor :name, :index, :version, :append_version, :attributes
6
-
7
- def initialize(name, attrs = {})
8
- attrs = {}.merge(attrs) # Important to keep this to clone the original options
9
- # so that the caller's copy if not affected by stripping
10
- # out the flow/relation options
11
- @attributes = {}
12
- @append_version = true
13
- self.name = name
14
- Origen.interface.extract_relation_options!(attrs)
15
- Origen.interface.extract_flow_control_options!(attrs)
16
- attrs.each do |attribute, val|
17
- @attributes[attribute] = val
18
- end
19
- end
20
-
21
- def to_yaml(options = {})
22
- {
23
- 'attributes' => attributes_to_yaml(options)
24
- }
25
- end
26
-
27
- def attributes_to_yaml(_options = {})
28
- a = {}
29
- @attributes.each do |name, val|
30
- a[name.to_s] = val if val
31
- end
32
- a['name'] = name
33
- a
34
- end
35
-
36
- def method_missing(method, *args, &_block)
37
- method = method.to_s
38
- if method.gsub!('=', '')
39
- @attributes[method] = args.first
40
- else
41
- @attributes[method]
42
- end
43
- end
44
-
45
- def ==(other_test)
46
- self.class == other_test.class &&
47
- unversioned_name.to_s == other_test.unversioned_name.to_s &&
48
- attributes.size == other_test.attributes.size &&
49
- attributes.all? { |name, val| other_test.attributes[name] == val }
50
- end
51
-
52
- def name
53
- if version && @append_version
54
- "#{@name}_v#{version}"
55
- else
56
- @name.to_s
57
- end
58
- end
59
-
60
- def unversioned_name
61
- @name.to_s
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,64 +0,0 @@
1
- module OrigenTesters
2
- class Doc
3
- module Generator
4
- class TestGroup
5
- attr_accessor :name, :version, :append_version
6
-
7
- include Enumerable
8
-
9
- def initialize(name, _options = {})
10
- @name = name
11
- @store = []
12
- @append_version = true
13
- end
14
-
15
- def name
16
- if unversioned_name
17
- if version && @append_version
18
- "#{unversioned_name}_v#{version}"
19
- else
20
- unversioned_name.to_s
21
- end
22
- end
23
- end
24
-
25
- def to_yaml(options = {})
26
- y = {}
27
- y['group'] = @store.map { |t| t.to_yaml(options) }
28
- y
29
- end
30
-
31
- def unversioned_name
32
- if @name
33
- if @name =~ /grp$/
34
- @name
35
- else
36
- "#{@name}_grp"
37
- end
38
- end
39
- end
40
-
41
- def <<(instance)
42
- @store << instance
43
- end
44
-
45
- def size
46
- @store.size
47
- end
48
-
49
- def each
50
- @store.each { |ins| yield ins }
51
- end
52
-
53
- def ==(other_instance_group)
54
- self.class == other_instance_group.class &&
55
- unversioned_name.to_s == other_instance_group.unversioned_name.to_s &&
56
- size == other_instance_group.size &&
57
- self.all? do |ins|
58
- other_instance_group.any? { |other_ins| ins == other_ins }
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,45 +0,0 @@
1
- module OrigenTesters
2
- class Doc
3
- module Generator
4
- class Tests
5
- attr_accessor :collection
6
-
7
- def initialize
8
- @collection = []
9
- end
10
-
11
- class IndexedString < ::String
12
- attr_accessor :index
13
-
14
- def name
15
- self
16
- end
17
- end
18
-
19
- def add(name, attrs = {})
20
- test = Test.new(name, attrs)
21
- if @current_group
22
- @current_group << test
23
- else
24
- collection << test
25
- end
26
- test
27
- end
28
-
29
- # Arbitrarily group a subset of tests together, see the J750 API for details on how to use
30
- # this.
31
- def group(name = nil, options = {})
32
- name, options = nil, name if name.is_a?(Hash)
33
- @current_group = TestGroup.new(name, options)
34
- collection << @current_group
35
- yield @current_group
36
- @current_group = nil
37
- end
38
- alias_method :add_group, :group
39
-
40
- def render(_file, _options = {})
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,160 +0,0 @@
1
- module OrigenTesters
2
- class Doc
3
- # Class representing a program model, provides an API to iterate
4
- # on the flow based on context (e.g. which job).
5
- class Model
6
- attr_accessor :flows, :target
7
-
8
- def initialize
9
- @flows = {}
10
- end
11
-
12
- # Iterates through each line in the given flow returning a hash for each
13
- # line with the following structure:
14
- #
15
- # {
16
- # :type => Symbol, # Type of flow line
17
- # :description => [], # Array of strings
18
- # :instance => [{}], # Array of attributes hashes (each one represents an individual test instance)
19
- # :flow => {}, # Hash of attributes
20
- # :context => {}, # Hash of attributes
21
- # }
22
- #
23
- # In all cases if an item is missing then it will be replaced by an empty
24
- # array or hash as appropriate so that the caller does not need to worry
25
- # about this.
26
- #
27
- # Supply the name of the flow(s) to consider, if the flows argument is left
28
- # out then all lines in all flows will be returned.
29
- #
30
- # A context option can be supplied to only return the tests for which the given
31
- # context is true.
32
- #
33
- # puts "The following tests run at FR:"
34
- # program_model.each_in_flow(:ft_flow, :context => { :job => "FR" }) do |line|
35
- # puts " #{line[:flow][:name]}"
36
- # end
37
- def each_in_flow(flows = nil, options = {})
38
- if flows.is_a?(Hash)
39
- options = flows
40
- flows = nil
41
- end
42
- unless flows
43
- flows = self.flows.keys
44
- end
45
- [flows].flatten.each do |flow|
46
- @flows[flow.to_sym].each do |test|
47
- test = format_test(test)
48
- if valid_in_context?(test, options[:context])
49
- yield test
50
- end
51
- end
52
- end
53
- nil
54
- end
55
-
56
- # Searches the given flows to find dependents of the given test id. The dependents
57
- # are returned in arrays grouped by context:
58
- #
59
- # {
60
- # :if_failed => [],
61
- # :if_passed => [],
62
- # :if_ran => [],
63
- # :unless_ran => [],
64
- # }
65
- #
66
- # Each test will have the same format as described in #each_in_flow.
67
- #
68
- # If no dependents are found an empty hash is returned.
69
- def dependents_of(id, flows, options = {})
70
- d = {}
71
- each_in_flow(flows, options) do |test|
72
- test[:context].each do |key, val|
73
- if val == id
74
- d[key] ||= []
75
- d[key] << test
76
- end
77
- end
78
- end
79
- d
80
- end
81
-
82
- # Search for the given test id in the given flows.
83
- # Returns nil if not found.
84
- def find_by_id(id, flows, options = {})
85
- each_in_flow(flows, options) do |test|
86
- return test if test[:flow][:id] == id
87
- end
88
- end
89
-
90
- # Returns true if the given tests id valid under the given context
91
- # (currently only tests for job matching)
92
- def valid_in_context?(test, context = nil)
93
- if context && context[:job] && test[:context]
94
- if test[:context][:if_jobs]
95
- test[:context][:if_jobs].include?(context[:job])
96
- elsif test[:context][:unless_jobs]
97
- !test[:context][:unless_jobs].include?(context[:job])
98
- else
99
- true
100
- end
101
- else
102
- true
103
- end
104
- end
105
-
106
- # @api private
107
- def format_test(test, _options = {})
108
- {
109
- type: test[:type] ? test[:type].to_sym : :unknown,
110
- description: test[:description] || [],
111
- instance: build_instance(test),
112
- flow: test[:flow] ? test[:flow][:attributes] || {} : {},
113
- context: test[:flow] ? test[:flow][:context] || {} : {}
114
- }
115
- end
116
-
117
- # @api private
118
- def build_instance(test)
119
- if test[:instance]
120
- if test[:instance][:group]
121
- test[:instance][:group].map { |g| g[:attributes] || {} }
122
- else
123
- [test[:instance][:attributes] || {}]
124
- end
125
- else
126
- [{}]
127
- end
128
- end
129
-
130
- # YAML likes strings for keys, we don't, so make sure all keys are symbols
131
- # when receiving a new flow
132
- # @api private
133
- def add_flow(name, content)
134
- @flows[name.to_sym] = content.map do |h|
135
- h = symbolize_keys h
136
- if h[:instance] && h[:instance][:group]
137
- h[:instance][:group] = h[:instance][:group].map { |j| symbolize_keys j }
138
- end
139
- h
140
- end
141
- end
142
-
143
- # @api private
144
- def symbolize_keys(hash)
145
- hash.reduce({}) do |result, (key, value)|
146
- new_key = case key
147
- when String then key.to_sym
148
- else key
149
- end
150
- new_value = case value
151
- when Hash then symbolize_keys(value)
152
- else value
153
- end
154
- result[new_key] = new_value
155
- result
156
- end
157
- end
158
- end
159
- end
160
- end
@@ -1,611 +0,0 @@
1
- module OrigenTesters
2
- module Generator
3
- module FlowControlAPI
4
- # Flow control methods related to flow context
5
- FLOW_METHODS = [
6
- # Methods in arrays are aliases, the primary name is the first one
7
- [:if_enable, :if_enabled, :enable, :enabled],
8
- [:unless_enable, :unless_enabled],
9
- [:if_job, :if_jobs],
10
- [:unless_job, :unless_jobs]
11
- ]
12
-
13
- # Flow control methods related to a relationship with another test
14
- RELATION_METHODS = [
15
- # Methods in arrays are aliases, the primary name is the first one
16
- :if_ran,
17
- :unless_ran,
18
- [:if_failed, :unless_passed],
19
- [:if_passed, :unless_failed],
20
- [:if_any_passed, :unless_all_failed],
21
- [:if_all_passed, :unless_any_failed],
22
- [:if_any_failed, :unless_all_passed],
23
- [:if_all_failed, :unless_any_passed]
24
- ]
25
-
26
- # Returns true if the test context generated from the supplied options + existing context
27
- # wrappers is different from that which was applied to the previous test.
28
- def context_changed?(options = {})
29
- current_context[:hash_code] != summarize_context(options)[:hash_code]
30
- end
31
-
32
- # @api private
33
- def save_context(options = {})
34
- # If the test has requested to use the current context...
35
- if options[:context] == :current
36
- replace_context_with_current(options)
37
- else
38
- @current_context = summarize_context(options)
39
- options.merge(@current_context[:context])
40
- end
41
- end
42
-
43
- # Returns a hash representing the current context, that is the context that was applied
44
- # to the last test.
45
- #
46
- # The hash contains two items:
47
- #
48
- # * :context contains a hash that summarises the flow control options that have been
49
- # used, for example it may contain something like: :if_enable => "data_collection"
50
- # * :hash_code returns a hash-code for the values contained in the :context arrary. Any
51
- # two equivalent contexts will have the same :hash_code, therefore this can be used
52
- # to easily check the equivalence of any two contexts.
53
- def current_context
54
- @current_context ||= save_context
55
- end
56
-
57
- # @api private
58
- #
59
- # Removes any context options from the given options hash and merges in the current
60
- # context
61
- def replace_context_with_current(options)
62
- options = options.merge({})
63
- [FLOW_METHODS, RELATION_METHODS].flatten.each do |m|
64
- options.delete(m)
65
- end
66
- options.merge(current_context[:context])
67
- end
68
-
69
- # Returns a hash like that returned by current_context based on the given set of options +
70
- # existing context wrappers.
71
- def summarize_context(options = {})
72
- code = []
73
- context = {}
74
- (FLOW_METHODS + RELATION_METHODS).each do |m|
75
- primary = m.is_a?(Array) ? m.first : m
76
- val = false
77
- [m].flatten.each do |m|
78
- if options[m]
79
- val = options[m]
80
- elsif instance_variable_get("@#{m}_block")
81
- val = instance_variable_get("@#{m}_block")
82
- end
83
- end
84
- if val
85
- code << primary
86
- code << val
87
- context[primary] = val
88
- end
89
- end
90
- { hash_code: code.flatten.hash, context: context }
91
- end
92
-
93
- # All tests generated within the given block will be assigned the given enable word.
94
- #
95
- # If a test encountered within the block already has another enable word assigned to it then
96
- # an error will be raised.
97
- def if_enable(word, options = {})
98
- @if_enable_block = word
99
- yield word
100
- @if_enable_block = nil
101
- end
102
- alias_method :if_enabled, :if_enable
103
-
104
- # All tests generated will not run unless the given enable word is asserted.
105
- def unless_enable(word, options = {})
106
- @unless_enable_block = word unless options[:or]
107
- yield word
108
- @unless_enable_block = nil
109
- end
110
- alias_method :unless_enabled, :unless_enable
111
-
112
- # All tests generated within the given block will be enabled only for the given jobs.
113
- def if_job(*jobs)
114
- jobs = jobs.flatten
115
- @if_job_block = @if_job_block ? @if_job_block + jobs : jobs
116
- yield
117
- @if_job_block = nil
118
- end
119
- alias_method :if_jobs, :if_job
120
-
121
- # All tests generated within the given block will be enabled only for the given jobs.
122
- def unless_job(*jobs)
123
- jobs = jobs.flatten
124
- @unless_job_block = @unless_job_block ? @unless_job_block + jobs : jobs
125
- yield
126
- @unless_job_block = nil
127
- end
128
- alias_method :unless_jobs, :unless_job
129
-
130
- # All tests generated within the given block will only run if the given test id has also
131
- # run earlier in the flow
132
- def if_ran(test_id, options = {})
133
- test_id = Origen.interface.filter_id(test_id, options)
134
- return if options.key?(:if) && !options[:if]
135
- return if options.key?(:unless) && options[:unless]
136
- if @if_ran_block
137
- fail 'Sorry but nesting of if_ran is not currently supported!'
138
- end
139
- @if_ran_block = test_id
140
- yield
141
- @if_ran_block = nil
142
- end
143
-
144
- # All tests generated within the given block will only run if the given test id has not
145
- # run earlier in the flow
146
- def unless_ran(test_id, options = {})
147
- test_id = Origen.interface.filter_id(test_id, options)
148
- return if options.key?(:if) && !options[:if]
149
- return if options.key?(:unless) && options[:unless]
150
- if @unless_ran_block
151
- fail 'Sorry but nesting of unless_ran is not currently supported!'
152
- end
153
- @unless_ran_block = test_id
154
- yield
155
- @unless_ran_block = nil
156
- end
157
-
158
- # All tests generated within the given block will only run if the given test id has
159
- # failed earlier in the flow
160
- def if_failed(test_id, options = {})
161
- test_id = Origen.interface.filter_id(test_id, options)
162
- return if options.key?(:if) && !options[:if]
163
- return if options.key?(:unless) && options[:unless]
164
- if @if_failed_block
165
- fail 'Sorry but nesting of if_failed is not currently supported!'
166
- end
167
- @if_failed_block = test_id
168
- yield
169
- @if_failed_block = nil
170
- end
171
- alias_method :unless_passed, :if_failed
172
-
173
- # All tests generated within the given block will only run if the given test id has
174
- # passed earlier in the flow
175
- def if_passed(test_id, options = {})
176
- test_id = Origen.interface.filter_id(test_id, options)
177
- return if options.key?(:if) && !options[:if]
178
- return if options.key?(:unless) && options[:unless]
179
- if @if_passed_block
180
- fail 'Sorry but nesting of if_passed is not currently supported!'
181
- end
182
- @if_passed_block = test_id
183
- yield
184
- @if_passed_block = nil
185
- end
186
- alias_method :unless_failed, :if_passed
187
-
188
- # All tests generated within the given block will only run if the given test id has
189
- # passed ON ANY SITE earlier in the flow
190
- def if_any_passed(test_id, options = {})
191
- test_id = Origen.interface.filter_id(test_id, options)
192
- return if conditionally_deactivated?(options)
193
- if @if_any_passed_block
194
- fail 'Sorry but nesting of if_any_passed is not currently supported!'
195
- end
196
- @if_any_passed_block = test_id
197
- yield
198
- @if_any_passed_block = nil
199
- end
200
- alias_method :unless_all_failed, :if_any_passed
201
-
202
- # All tests generated within the given block will only run if the given test id has
203
- # passed ON ALL SITES earlier in the flow
204
- def if_all_passed(test_id, options = {})
205
- test_id = Origen.interface.filter_id(test_id, options)
206
- return if conditionally_deactivated?(options)
207
- if @if_all_passed_block
208
- fail 'Sorry but nesting of if_all_passed is not currently supported!'
209
- end
210
- @if_all_passed_block = test_id
211
- yield
212
- @if_all_passed_block = nil
213
- end
214
- alias_method :unless_any_failed, :if_all_passed
215
-
216
- # All tests generated within the given block will only run if the given test id has
217
- # failed ON ANY SITE earlier in the flow
218
- def if_any_failed(test_id, options = {})
219
- test_id = Origen.interface.filter_id(test_id, options)
220
- return if conditionally_deactivated?(options)
221
- if @if_any_failed_block
222
- fail 'Sorry but nesting of if_any_failed is not currently supported!'
223
- end
224
- @if_any_failed_block = test_id
225
- yield
226
- @if_any_failed_block = nil
227
- end
228
- alias_method :unless_all_passed, :if_any_failed
229
-
230
- # All tests generated within the given block will only run if the given test id has
231
- # failed ON ALL SITES earlier in the flow
232
- def if_all_failed(test_id, options = {})
233
- test_id = Origen.interface.filter_id(test_id, options)
234
- return if conditionally_deactivated?(options)
235
- if @if_all_failed_block
236
- fail 'Sorry but nesting of if_all_failed is not currently supported!'
237
- end
238
- @if_all_failed_block = test_id
239
- yield
240
- @if_all_failed_block = nil
241
- end
242
- alias_method :unless_any_passed, :if_all_failed
243
-
244
- def conditionally_deactivated?(options)
245
- (options.key?(:if) && !options[:if]) ||
246
- (options.key?(:unless) && options[:unless])
247
- end
248
-
249
- def find_by_id(id, options = {}) # :nodoc:
250
- options = {
251
- search_other_flows: true
252
- }.merge(options)
253
- # Look within the current flow for a match first
254
- t = identity_map[id.to_sym]
255
- return t if t
256
- # If no match then look across other flow modules for a match
257
- # This currently returns the first match, should it raise an error on multiple?
258
- if options[:search_other_flows]
259
- Origen.interface.flow_generators.any? do |flow|
260
- t = flow.find_by_id(id, search_other_flows: false)
261
- end
262
- end
263
- t
264
- end
265
-
266
- def identity_map # :nodoc:
267
- @identity_map ||= {}
268
- end
269
-
270
- # If a class that includes this module has a finalize method it must
271
- # call apply_relationships
272
- def finalize(options = {}) # :nodoc:
273
- apply_relationships
274
- reset_globals
275
- end
276
-
277
- def apply_relationships # :nodoc:
278
- if @relationships
279
- @relationships.each do |rel|
280
- t = find_by_id(rel[:target_id])
281
- fail "Test not found with ID: #{rel[:target_id]}, referenced in flow: #{filename}" unless t
282
- t.id = rel[:target_id]
283
- confirm_valid_context(t, rel[:dependent])
284
- case rel[:type]
285
- # The first cases here contain J750 logic, these should be replaced
286
- # with the call method style used for the later cases when time permits.
287
- when :failed
288
- if rel[:dependent].respond_to?(:run_if_failed)
289
- rel[:dependent].run_if_failed(rel[:target_id])
290
- else
291
- t.continue_on_fail
292
- flag = t.set_flag_on_fail
293
- rel[:dependent].flag_true = flag
294
- end
295
- when :passed
296
- if rel[:dependent].respond_to?(:run_if_passed)
297
- rel[:dependent].run_if_passed(rel[:target_id])
298
- else
299
- t.continue_on_fail
300
- flag = t.set_flag_on_pass
301
- rel[:dependent].flag_true = flag
302
- end
303
- when :if_ran, :unless_ran
304
- if rel[:type] == :if_ran
305
- if rel[:dependent].respond_to?(:run_if_ran)
306
- rel[:dependent].run_if_ran(rel[:target_id])
307
- else
308
- # t.continue_on_fail
309
- flag = t.set_flag_on_ran
310
- rel[:dependent].flag_true = flag
311
- end
312
- else
313
- if rel[:dependent].respond_to?(:run_unless_ran)
314
- rel[:dependent].run_unless_ran(rel[:target_id])
315
- else
316
- # t.continue_on_fail
317
- flag = t.set_flag_on_ran
318
- rel[:dependent].flag_clear = flag
319
- end
320
- end
321
- when :any_passed
322
- rel[:dependent].run_if_any_passed(t)
323
- when :all_passed
324
- rel[:dependent].run_if_all_passed(t)
325
- when :any_failed
326
- rel[:dependent].run_if_any_failed(t)
327
- when :all_failed
328
- rel[:dependent].run_if_all_failed(t)
329
- else
330
- fail 'Unknown relationship type!'
331
- end
332
- end
333
- @relationships = nil
334
- end
335
- end
336
-
337
- def confirm_valid_context(test, dependent) # :nodoc:
338
- # TODO: Add some validation checks here, for example make sure the dependent
339
- # executes in the same job(s) as the test, otherwise the dependent will
340
- # never be hit and will cause a validation error.
341
- end
342
-
343
- def record_id(test, options = {})
344
- if options[:id]
345
- @@existing_ids ||= []
346
- if @@existing_ids.include?(options[:id].to_sym)
347
- fail "The ID '#{test.id}' is not unique, it has already been assigned!"
348
- else
349
- @@existing_ids << options[:id].to_sym
350
- end
351
- identity_map[options[:id].to_sym] = test
352
- end
353
- end
354
-
355
- # @api private
356
- def at_run_start
357
- @@existing_ids = nil
358
- @@labels = nil
359
- end
360
- alias_method :reset_globals, :at_run_start
361
-
362
- def replace_relationship_dependent(old_node, new_node)
363
- @relationships.each do |rel|
364
- rel[:dependent] = new_node if rel[:dependent] == old_node
365
- end
366
- end
367
-
368
- # As generation of render and imports is not linear its possible that the test being
369
- # referenced does not exist in the collection yet.
370
- # Therefore the required relationship will be recorded for now and applied later upon
371
- # closing the generator at which point the complete final collection will be available.
372
- #
373
- # Note - as of v2.0.1.dev64 the above is no longer true - imports are generated linearly.
374
- # Therefore parent test should always already exist and it is possible that this relationship
375
- # handling could be cleaned up considerably.
376
- #
377
- # However we should keep it around for now as it may come in useful when other tester
378
- # platforms are supported in the future.
379
- def track_relationships(test_options = {}) # :nodoc:
380
- [:id, RELATION_METHODS].flatten.each do |id|
381
- if test_options[id]
382
- test_options[id] = Origen.interface.filter_id(test_options[id], test_options)
383
- end
384
- end
385
- options = extract_relation_options!(test_options)
386
- current_test = yield test_options
387
- record_id(current_test, test_options)
388
- @relationships ||= []
389
- target_id = options[:if_failed] || options[:unless_passed] || @if_failed_block
390
- if target_id
391
- @relationships << {
392
- type: :failed,
393
- target_id: target_id,
394
- dependent: current_test
395
- }
396
- end
397
- target_id = options[:if_passed] || options[:unless_failed] || @if_passed_block
398
- if target_id
399
- @relationships << {
400
- type: :passed,
401
- target_id: target_id,
402
- dependent: current_test
403
- }
404
- end
405
- target_id = options.delete(:if_ran) || @if_ran_block
406
- if target_id
407
- @relationships << {
408
- type: :if_ran,
409
- target_id: target_id,
410
- dependent: current_test
411
- }
412
- end
413
- target_id = options.delete(:unless_ran) || @unless_ran_block
414
- if target_id
415
- @relationships << {
416
- type: :unless_ran,
417
- target_id: target_id,
418
- dependent: current_test
419
- }
420
- end
421
- target_id = options[:if_any_passed] || options[:unless_all_failed] || @if_any_passed_block
422
- if target_id
423
- @relationships << {
424
- type: :any_passed,
425
- target_id: target_id,
426
- dependent: current_test
427
- }
428
- end
429
- target_id = options[:if_all_passed] || options[:unless_any_failed] || @if_all_passed_block
430
- if target_id
431
- @relationships << {
432
- type: :all_passed,
433
- target_id: target_id,
434
- dependent: current_test
435
- }
436
- end
437
- target_id = options[:if_any_failed] || options[:unless_all_passed] || @if_any_failed_block
438
- if target_id
439
- @relationships << {
440
- type: :any_failed,
441
- target_id: target_id,
442
- dependent: current_test
443
- }
444
- end
445
- target_id = options[:if_all_failed] || options[:unless_any_passed] || @if_all_failed_block
446
- if target_id
447
- @relationships << {
448
- type: :all_failed,
449
- target_id: target_id,
450
- dependent: current_test
451
- }
452
- end
453
- if test_options[:context] == :current # Context has already been applied
454
- current_test
455
- else
456
- apply_current_context!(current_test)
457
- end
458
- end
459
-
460
- def apply_current_context!(line) # :nodoc:
461
- if @if_enable_block
462
- if line.enable && line.enable != @if_enable_block
463
- fail "Cannot apply enable word '#{@if_enable_block}' to '#{line.parameter}', it already has '#{line.enable}'"
464
- else
465
- line.enable = @if_enable_block
466
- end
467
- end
468
- if @unless_enable_block
469
- line.unless_enable = @unless_enable_block
470
- end
471
- line.if_job = @if_job_block if @if_job_block
472
- line.unless_job = @unless_job_block if @unless_job_block
473
- line
474
- end
475
-
476
- # Removes any flow relationship options from given hash and returns them
477
- # in a new hash
478
- def extract_relation_options!(options) # :nodoc:
479
- opts = {}
480
- RELATION_METHODS.flatten.each do |o|
481
- opts[o] = options.delete(o)
482
- end
483
- opts
484
- end
485
-
486
- def extract_flow_control_options!(options)
487
- opts = {}
488
- FLOW_METHODS.flatten.each do |o|
489
- if options.key?(o)
490
- opts[o] = options.delete(o)
491
- end
492
- end
493
- opts
494
- end
495
-
496
- def generate_unique_label(id = nil)
497
- id = 'label' if !id || id == ''
498
- label = "#{Origen.interface.app_identifier}_#{id}"
499
- label.gsub!(' ', '_')
500
- label.upcase!
501
- @@labels ||= {}
502
- @@labels[Origen.tester.class] ||= {}
503
- @@labels[Origen.tester.class][label] ||= 0
504
- @@labels[Origen.tester.class][label] += 1
505
- "#{label}_#{@@labels[Origen.tester.class][label]}"
506
- end
507
-
508
- module Interface
509
- # Implement this method in your application interface if you want to
510
- # sanitize all ID references used in the flow control API.
511
- # For example you could use this to append a flow name prefix to every
512
- # ID reference within a flow which can help with ID duplication problems
513
- # when flow snippets are re-used.
514
- def filter_id(id, options = {})
515
- id
516
- end
517
-
518
- def extract_relation_options!(*args)
519
- flow.extract_relation_options!(*args)
520
- end
521
-
522
- def extract_flow_control_options!(*args)
523
- flow.extract_flow_control_options!(*args)
524
- end
525
-
526
- # Alias for flow#if_enable
527
- def if_enable(*args, &block)
528
- flow.if_enable(*args, &block)
529
- end
530
- alias_method :if_enabled, :if_enable
531
-
532
- # Alias for flow#unless_enable
533
- def unless_enable(*args, &block)
534
- flow.unless_enable(*args, &block)
535
- end
536
- alias_method :unless_enabled, :unless_enable
537
-
538
- # Alias for flow#if_job
539
- def if_job(*args, &block)
540
- flow.if_job(*args, &block)
541
- end
542
-
543
- # Alias for flow#unless_job
544
- def unless_job(*args, &block)
545
- flow.unless_job(*args, &block)
546
- end
547
-
548
- # Alias for flow#unless_ran
549
- def unless_ran(*args, &block)
550
- flow.unless_ran(*args, &block)
551
- end
552
-
553
- # Alias for flow#if_ran
554
- def if_ran(*args, &block)
555
- flow.if_ran(*args, &block)
556
- end
557
-
558
- # Alias for flow#if_failed
559
- def if_failed(*args, &block)
560
- flow.if_failed(*args, &block)
561
- end
562
- alias_method :unless_passed, :if_failed
563
-
564
- # Alias for flow#if_passed
565
- def if_passed(*args, &block)
566
- flow.if_passed(*args, &block)
567
- end
568
- alias_method :unless_failed, :if_passed
569
-
570
- # Alias for flow#if_any_passed
571
- def if_any_passed(*args, &block)
572
- flow.if_any_passed(*args, &block)
573
- end
574
- alias_method :unless_all_failed, :if_any_passed
575
-
576
- # Alias for flow#if_all_passed
577
- def if_all_passed(*args, &block)
578
- flow.if_all_passed(*args, &block)
579
- end
580
- alias_method :unless_any_failed, :if_all_passed
581
-
582
- # Alias for flow#if_any_failed
583
- def if_any_failed(*args, &block)
584
- flow.if_any_failed(*args, &block)
585
- end
586
- alias_method :unless_all_passed, :if_any_failed
587
-
588
- # Alias for flow#if_all_failed
589
- def if_all_failed(*args, &block)
590
- flow.if_all_failed(*args, &block)
591
- end
592
- alias_method :unless_any_passed, :if_all_failed
593
-
594
- # Alias for flow#skip
595
- def skip(*args, &block)
596
- flow.skip(*args, &block)
597
- end
598
-
599
- # Alias for flow#current_context
600
- def current_context(*args, &block)
601
- flow.current_context(*args, &block)
602
- end
603
-
604
- # Alias for flow#context_changed?
605
- def context_changed?(*args, &block)
606
- flow.context_changed?(*args, &block)
607
- end
608
- end
609
- end
610
- end
611
- end