origen_testers 0.5.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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