origen_testers 0.51.2 → 0.51.3
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 +4 -4
- data/config/commands.rb +1 -1
- data/config/version.rb +1 -1
- data/lib/origen_testers/charz/profile.rb +16 -1
- data/lib/origen_testers/charz/session.rb +125 -60
- data/lib/origen_testers/charz.rb +171 -100
- data/program/charz.rb +5 -0
- data/templates/origen_guides/program/charz.md.erb +74 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3762e544f419c1c77e9f1d670c7203cd44e9ad6fef0246463f62c77e8592be92
|
4
|
+
data.tar.gz: 3c2e4679fae95dbb6f9976be317bbcf6c9fe3f8eff113d40fbdafe68cea06973
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 563af43372ac16a7159e4f1ca6d8aa8aed2fc630dc9224f477cb427332f76ec9ada304428caa15695cf48e7923fa3243154de71bc12b737e170d5370946a44f3
|
7
|
+
data.tar.gz: 2674ab9dda1e9b8e6a7816d5cab6add7eb9dc44b037ac2b12ef46a5d2473324632034faf88cf34998d501140eda7545a7ac19a8e0710ffb062c5523f93bdff49
|
data/config/commands.rb
CHANGED
@@ -175,7 +175,7 @@ when "tags"
|
|
175
175
|
# Run the unit tests
|
176
176
|
when "specs"
|
177
177
|
require "rspec"
|
178
|
-
exit RSpec::Core::Runner.run(['spec'])
|
178
|
+
exit RSpec::Core::Runner.run($ARGV.empty? ? ['spec'] : $ARGV)
|
179
179
|
|
180
180
|
# Run the example-based (diff) tests
|
181
181
|
when "examples", "test"
|
data/config/version.rb
CHANGED
@@ -19,7 +19,7 @@ module OrigenTesters
|
|
19
19
|
# @return [Array] list of charz routines to be called under this profile
|
20
20
|
# @!attribute charz_only
|
21
21
|
# @return [Boolean] indicates if the point tests should or shouldn't be added to the flow
|
22
|
-
attr_accessor :id, :name, :placement, :on_result, :enables, :flags, :routines, :charz_only, :and_enables, :and_flags
|
22
|
+
attr_accessor :id, :name, :placement, :on_result, :enables, :flags, :routines, :charz_only, :force_keep_parent, :and_enables, :and_flags
|
23
23
|
|
24
24
|
def initialize(id, options, &block)
|
25
25
|
@id = id
|
@@ -30,6 +30,7 @@ module OrigenTesters
|
|
30
30
|
@placement ||= :inline
|
31
31
|
@defined_routines = options.delete(:defined_routines)
|
32
32
|
attrs_ok?
|
33
|
+
massage_gates
|
33
34
|
end
|
34
35
|
|
35
36
|
def attrs_ok?
|
@@ -91,6 +92,20 @@ module OrigenTesters
|
|
91
92
|
end
|
92
93
|
end
|
93
94
|
|
95
|
+
# convert hash gates to set convert their routines to type array if not already
|
96
|
+
def massage_gates
|
97
|
+
if @enables.is_a?(Hash)
|
98
|
+
@enables = {}.tap do |new_h|
|
99
|
+
@enables.each { |gates, routines| new_h[gates] = [routines].flatten }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
if @flags.is_a?(Hash)
|
103
|
+
@flags = {}.tap do |new_h|
|
104
|
+
@flags.each { |gates, routines| new_h[gates] = [routines].flatten }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
94
109
|
def gate_check(gates, gate_type)
|
95
110
|
case gates
|
96
111
|
when Symbol, String
|
@@ -1,30 +1,59 @@
|
|
1
1
|
module OrigenTesters
|
2
2
|
module Charz
|
3
3
|
# A charz session
|
4
|
-
# contains the final
|
4
|
+
# contains a collection of the final combinations of charz object (routines/profiles) and user options to determine how and what charz tests should be created
|
5
5
|
# the session should be checked in your interface to determine the current status and can be queried to make charz generation decisions
|
6
|
-
class Session
|
6
|
+
class Session
|
7
|
+
# @!attribute id
|
8
|
+
# @return [Symbol] current session ID. Will be a concatenation of the instances' ids
|
9
|
+
# @!attribute instances
|
10
|
+
# @return [Array] list of active instances (which are essentially Profiles)
|
11
|
+
# @!attribute current_instance
|
12
|
+
# @return [Profile] Set when looping over instances via #loop_instances. The interface can query the charz_instance for more detailed info
|
13
|
+
# @!attribute valid
|
14
|
+
# @return [Boolean] whether or not the current session setup is valid, if not then charz wont be created
|
7
15
|
# @!attribute defaults
|
8
16
|
# @return [Hash] list of values to instantiate the inherited attributes from Profile with if not altered by the session update
|
9
|
-
|
17
|
+
# @!attribute stored_instance
|
18
|
+
# @return [Profile] This is to store the instance that the interface is storing. Its to support a legacy usecase of querying the session for instance level info during EOF
|
19
|
+
attr_accessor :id, :instances, :current_instance, :valid, :defaults, :stored_instance
|
10
20
|
|
11
21
|
def initialize(options = {})
|
12
|
-
@id = :
|
22
|
+
@id = :empty_session
|
23
|
+
@instances = []
|
24
|
+
@current_instance = nil
|
25
|
+
@stored_instance = nil
|
13
26
|
@active = false
|
14
27
|
@valid = false
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
@defaults = {
|
29
|
+
placement: :inline,
|
30
|
+
routines: [],
|
31
|
+
on_result: nil,
|
32
|
+
enables: nil,
|
33
|
+
flags: nil,
|
34
|
+
enables_and: false,
|
35
|
+
and_enables: false,
|
36
|
+
flags_and: false,
|
37
|
+
and_flags: false,
|
38
|
+
name: 'charz',
|
39
|
+
charz_only: false,
|
40
|
+
force_keep_parent: false
|
41
|
+
}.merge((options[:defaults] || {}))
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_result?
|
45
|
+
instances.any? { |charz_instance| !charz_instance.on_result.nil? }
|
46
|
+
end
|
47
|
+
|
48
|
+
def charz_only?
|
49
|
+
any_only = instances.any?(&:charz_only)
|
50
|
+
any_force = instances.any?(&:force_keep_parent)
|
51
|
+
!any_force && any_only && !on_result?
|
52
|
+
end
|
53
|
+
|
54
|
+
def charz_only
|
55
|
+
Origen.log.deprecate '#charz_only has been deprecated in favor of #charz_only? It is no longer an attribute, instead a runtime calculation.'
|
56
|
+
charz_only?
|
28
57
|
end
|
29
58
|
|
30
59
|
# Pauses the current session's activity while maintaining everthing else about the sessions state
|
@@ -32,6 +61,11 @@ module OrigenTesters
|
|
32
61
|
@active = false
|
33
62
|
end
|
34
63
|
|
64
|
+
def active?
|
65
|
+
!!@active
|
66
|
+
end
|
67
|
+
alias_method :active, :active?
|
68
|
+
|
35
69
|
# Resume activity, if the session is valid
|
36
70
|
def resume
|
37
71
|
if @valid
|
@@ -39,72 +73,103 @@ module OrigenTesters
|
|
39
73
|
end
|
40
74
|
end
|
41
75
|
|
42
|
-
|
76
|
+
def current_instance
|
77
|
+
instance = @current_instance || instances.first
|
78
|
+
if instance.nil? && @stored_instance
|
79
|
+
Origen.log.deprecate '@current_instance had to source @stored_instance. This likely means charz_session.<some_attr> is being queried when the newer charz_instance.<some_attr> should be instead'
|
80
|
+
instance = @stored_instance
|
81
|
+
end
|
82
|
+
instance
|
83
|
+
end
|
84
|
+
|
85
|
+
def loop_instances
|
86
|
+
instances.each do |charz_instance|
|
87
|
+
@current_instance = charz_instance
|
88
|
+
yield
|
89
|
+
@current_instance = nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Takes a CharzTuple and queries it to setup an instance's attributes
|
43
94
|
# the attributes values can be set from 3 different sources, in order of priority (first is most important):
|
44
95
|
# - options
|
45
|
-
# - charz object
|
96
|
+
# - charz object (Profile or Routine)
|
46
97
|
# - defaults
|
47
98
|
#
|
48
99
|
# If the resulting session is invalid, @valid will turn false. Otherwise, the session becomes active
|
49
|
-
def update(
|
100
|
+
def update(charz_tuples)
|
101
|
+
@instances = []
|
50
102
|
@valid = false
|
51
|
-
if
|
103
|
+
if charz_tuples.nil? || charz_tuples.empty?
|
52
104
|
@active = false
|
53
105
|
@valid = false
|
106
|
+
@current_instance = nil
|
54
107
|
return @valid
|
55
108
|
end
|
56
|
-
@defined_routines =
|
109
|
+
@defined_routines = charz_tuples.map(&:defined_routines).flatten.uniq.compact
|
57
110
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
@and_flags = false
|
62
|
-
end
|
63
|
-
if charz_obj.and_enables
|
64
|
-
@and_enables = charz_obj.and_enables
|
65
|
-
else
|
66
|
-
@and_enables = false
|
111
|
+
charz_tuples.each do |charz_tuple|
|
112
|
+
profile_options = assign_by_priority(charz_tuple)
|
113
|
+
@instances << Profile.new(charz_tuple.obj.id, profile_options.merge(defined_routines: @defined_routines))
|
67
114
|
end
|
68
|
-
|
69
|
-
assign_by_priority(:on_result, charz_obj, options)
|
70
|
-
assign_by_priority(:enables, charz_obj, options)
|
71
|
-
assign_by_priority(:flags, charz_obj, options)
|
72
|
-
assign_by_priority(:routines, charz_obj, options)
|
73
|
-
assign_by_priority(:name, charz_obj, options)
|
74
|
-
assign_by_priority(:charz_only, charz_obj, options)
|
75
|
-
attrs_ok?
|
76
|
-
massage_gates
|
115
|
+
@id = instances.map(&:id).join('_').to_sym
|
77
116
|
@active = true
|
78
117
|
@valid = true
|
79
118
|
end
|
80
119
|
|
81
120
|
private
|
82
121
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
122
|
+
def assign_by_priority(charz_tuple)
|
123
|
+
options = charz_tuple.options
|
124
|
+
charz_obj = charz_tuple.obj
|
125
|
+
instance_options = {}
|
126
|
+
get_instance_setting_keys(charz_obj).each do |ivar|
|
127
|
+
if options.keys.include?(ivar)
|
128
|
+
instance_options[ivar] = options[ivar]
|
129
|
+
elsif charz_obj.send(ivar)
|
130
|
+
instance_options[ivar] = charz_obj.send(ivar)
|
131
|
+
elsif @defaults.keys.include?(ivar)
|
132
|
+
instance_options[ivar] = @defaults[ivar]
|
133
|
+
else
|
134
|
+
Origen.log.error "Charz Session: No value could be determined for #{ivar}"
|
135
|
+
fail
|
93
136
|
end
|
94
137
|
end
|
138
|
+
instance_options
|
95
139
|
end
|
96
140
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
141
|
+
def get_instance_setting_keys(charz_obj)
|
142
|
+
keys = charz_obj.instance_variables | @defaults.keys
|
143
|
+
keys.map! { |k| k.to_s.sub('@', '').to_sym }
|
144
|
+
keys -= [:id]
|
145
|
+
keys
|
146
|
+
end
|
147
|
+
|
148
|
+
def method_missing(method, *args, &block)
|
149
|
+
deprecated_methods = [
|
150
|
+
:name,
|
151
|
+
:placement,
|
152
|
+
:on_result,
|
153
|
+
:enables,
|
154
|
+
:flags,
|
155
|
+
:routines,
|
156
|
+
:and_enables,
|
157
|
+
:enables_and,
|
158
|
+
:and_flags,
|
159
|
+
:flags_and,
|
160
|
+
:charz_only,
|
161
|
+
:force_keep_parent
|
162
|
+
]
|
163
|
+
if deprecated_methods.include?(method.to_sym) || deprecated_methods.include?(method.to_s[0..-2].to_sym)
|
164
|
+
Origen.log.deprecate "charz_session.#{method} has been deprecated. Please query charz_instance.#{method} instead."
|
165
|
+
if current_instance.nil? && !valid
|
166
|
+
Origen.log.error "blocked call of 'charz_session.#{method}'!"
|
167
|
+
Origen.log.warn 'The charz instance attributes are no longer accessible when the session is invalid!'
|
168
|
+
else
|
169
|
+
current_instance.send(method, *args, &block)
|
170
|
+
end
|
105
171
|
else
|
106
|
-
|
107
|
-
fail
|
172
|
+
super
|
108
173
|
end
|
109
174
|
end
|
110
175
|
end
|
data/lib/origen_testers/charz.rb
CHANGED
@@ -3,6 +3,7 @@ Dir.glob("#{File.dirname(__FILE__)}/charz/**/*.rb").sort.each do |file|
|
|
3
3
|
end
|
4
4
|
module OrigenTesters
|
5
5
|
module Charz
|
6
|
+
CharzTuple = Struct.new(:obj, :options, :defined_routines, keyword_init: true)
|
6
7
|
# @!attribute charz_stack
|
7
8
|
# @return [Array] FILO queue of charz session defining data
|
8
9
|
# @!attribute charz_routines
|
@@ -11,13 +12,15 @@ module OrigenTesters
|
|
11
12
|
# @return [Hash] user defined charz profiles
|
12
13
|
# @!attribute charz_session
|
13
14
|
# @return [Session] current charz session, based on data in the top of the charz_stack
|
15
|
+
# @!attribute charz_instance
|
16
|
+
# @return [Session] current charz instance of the session. If there is not a current instance, will return the first instance of the session instance stack
|
14
17
|
# @!attribute eof_charz_tests
|
15
18
|
# @return [Array] charz tests to be added at the end of the flow
|
16
19
|
# @!attribute skip_group_eof_charz_tests
|
17
20
|
# @return [Boolean] whether or not to wrap eof charz tests in a group
|
18
21
|
# @!attribute eof_charz_tests_group_name
|
19
22
|
# @return [String, Symbol] group name to be used to for eof charz tests
|
20
|
-
attr_accessor :charz_stack, :charz_routines, :charz_profiles, :charz_session, :eof_charz_tests, :skip_group_eof_charz_tests, :eof_charz_tests_group_name
|
23
|
+
attr_accessor :charz_stack, :charz_routines, :charz_profiles, :charz_session, :charz_instance, :eof_charz_tests, :skip_group_eof_charz_tests, :eof_charz_tests_group_name
|
21
24
|
|
22
25
|
def charz_stack
|
23
26
|
@charz_stack ||= []
|
@@ -35,6 +38,21 @@ module OrigenTesters
|
|
35
38
|
@charz_session ||= Session.new
|
36
39
|
end
|
37
40
|
|
41
|
+
# If there is a current instance present, that should always be used. However when running EOF charz,
|
42
|
+
# the instance to be used is no longer set, so instead of referencing the session, use the one that we've
|
43
|
+
# stored already
|
44
|
+
def charz_instance
|
45
|
+
unless charz_session.current_instance.nil?
|
46
|
+
set_charz_instance(charz_session.current_instance)
|
47
|
+
end
|
48
|
+
@charz_instance
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_charz_instance(instance)
|
52
|
+
@charz_instance = instance
|
53
|
+
charz_session.stored_instance = instance
|
54
|
+
end
|
55
|
+
|
38
56
|
def eof_charz_tests
|
39
57
|
@eof_charz_tests ||= []
|
40
58
|
end
|
@@ -106,12 +124,12 @@ module OrigenTesters
|
|
106
124
|
|
107
125
|
# Queries the current charz session to see if its active, indicating point tests should be generating charz tests
|
108
126
|
def charz_active?
|
109
|
-
charz_session.active
|
127
|
+
charz_session.active?
|
110
128
|
end
|
111
129
|
|
112
130
|
# Queries the current charz session to see if point tests should skip generation, only adding the resulting charz test
|
113
131
|
def charz_only?
|
114
|
-
charz_active? && charz_session.charz_only
|
132
|
+
charz_active? && charz_session.charz_only?
|
115
133
|
end
|
116
134
|
|
117
135
|
# Pauses the current charz session, preventing point tests from generating charz tests even if the session is valid
|
@@ -129,10 +147,12 @@ module OrigenTesters
|
|
129
147
|
# if not, the session will become inactive
|
130
148
|
def charz_off
|
131
149
|
charz_stack.pop
|
150
|
+
unless charz_session.update(charz_stack.last) || charz_stack.empty?
|
151
|
+
Origen.log.error 'charz_on failed to create a valid charz session'
|
152
|
+
fail
|
153
|
+
end
|
132
154
|
if charz_stack.empty?
|
133
|
-
|
134
|
-
else
|
135
|
-
update_charz_session(*charz_stack.last)
|
155
|
+
set_charz_instance(nil)
|
136
156
|
end
|
137
157
|
end
|
138
158
|
|
@@ -145,36 +165,61 @@ module OrigenTesters
|
|
145
165
|
# @param [Hash] options charz_on options
|
146
166
|
# @option options [Symbol] :type (:profile) whether the charz_id refers to a charz profile or routine
|
147
167
|
def charz_on(charz_id, options = {})
|
148
|
-
options
|
149
|
-
|
150
|
-
|
151
|
-
case options[:type]
|
152
|
-
when :profile
|
153
|
-
charz_obj = charz_profiles[charz_id]
|
154
|
-
when :routine
|
155
|
-
if charz_id.is_a?(Array)
|
156
|
-
charz_obj = charz_routines[charz_id.first]
|
157
|
-
options[:routines] = charz_id
|
158
|
-
else
|
159
|
-
charz_obj = charz_routines[charz_id]
|
160
|
-
options[:routines] = [charz_id]
|
161
|
-
end
|
162
|
-
else
|
163
|
-
Origen.log.error "Unknown charz object type #{options[:type]}, valid types: :profile, :routine"
|
168
|
+
charz_stack.push([get_charz_tuple(charz_id, options)])
|
169
|
+
unless charz_session.update(charz_stack.last)
|
170
|
+
Origen.log.error 'charz_on failed to create a valid charz session'
|
164
171
|
fail
|
165
172
|
end
|
166
|
-
if
|
167
|
-
|
168
|
-
|
173
|
+
if block_given?
|
174
|
+
yield
|
175
|
+
charz_off
|
169
176
|
end
|
170
|
-
|
171
|
-
|
177
|
+
end
|
178
|
+
|
179
|
+
# Pushes a charz object (either a profile or a routine) onto the current sessions instance stack, along with any optional updates to modify that instance.
|
180
|
+
# This will result in subsequent charzable point tests in being processed against each of the current instances. In other words, this new push will not
|
181
|
+
# take priority over the current stack head, but instead append to it.
|
182
|
+
# Once pushed, the charz_session will attempt to update itself with the new data, failing if the resulting session is invalid
|
183
|
+
#
|
184
|
+
# If a block is passed, yield the block of tests to enable charz for those tests, then disable charz with a charz_off_truncate call
|
185
|
+
#
|
186
|
+
# @param [Symbol] charz_id either a routine or profile id. Method fails if the id can't be found in @charz_routines or @charz_profiles
|
187
|
+
# @param [Hash] options charz_on options
|
188
|
+
# @option options [Symbol] :type (:profile) whether the charz_id refers to a charz profile or routine
|
189
|
+
def charz_on_append(charz_id, options = {})
|
190
|
+
charz_tuple = get_charz_tuple(charz_id, options)
|
191
|
+
|
192
|
+
# take the current session and append to its instance stack
|
193
|
+
session = charz_stack.pop || []
|
194
|
+
session.push(charz_tuple)
|
195
|
+
charz_stack.push(session)
|
196
|
+
|
197
|
+
unless charz_session.update(charz_stack.last)
|
172
198
|
Origen.log.error 'charz_on failed to create a valid charz session'
|
173
199
|
fail
|
174
200
|
end
|
175
201
|
if block_given?
|
176
202
|
yield
|
177
|
-
|
203
|
+
charz_off_truncate
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Removes the current sessions last instance. If the session only had one instance, this is functionally the same as charz_off
|
208
|
+
# If charz data is still on the stack afterward, the session will update to reflect the new data
|
209
|
+
# if not, the session will become inactive
|
210
|
+
def charz_off_truncate
|
211
|
+
session = charz_stack.pop || []
|
212
|
+
session.pop
|
213
|
+
unless session.empty?
|
214
|
+
charz_stack.push(session)
|
215
|
+
end
|
216
|
+
|
217
|
+
unless charz_session.update(charz_stack.last) || charz_stack.empty?
|
218
|
+
Origen.log.error 'charz_on failed to create a valid charz session'
|
219
|
+
fail
|
220
|
+
end
|
221
|
+
if charz_stack.empty?
|
222
|
+
set_charz_instance(nil)
|
178
223
|
end
|
179
224
|
end
|
180
225
|
|
@@ -196,8 +241,12 @@ module OrigenTesters
|
|
196
241
|
end
|
197
242
|
unless options[:id]
|
198
243
|
if charz_active?
|
199
|
-
if charz_session.on_result
|
200
|
-
|
244
|
+
if charz_session.on_result?
|
245
|
+
md5_id = Digest::MD5.new
|
246
|
+
md5_id << parent_test_name.to_s
|
247
|
+
md5_id << options.to_s
|
248
|
+
md5_id << charz_session.id.to_s
|
249
|
+
options[:id] = "auto_charz_id_#{md5_id}".to_sym
|
201
250
|
end
|
202
251
|
end
|
203
252
|
end
|
@@ -206,7 +255,7 @@ module OrigenTesters
|
|
206
255
|
# Called after the relevant point test has been inserted into the flow
|
207
256
|
# Takes the options used to build the previous point test as well as insert_charz_test specific options to then
|
208
257
|
# drill down to the point of the flow where the charz test would go, at which point control is handed back to the user's
|
209
|
-
# interface to handle creating and inserting the test
|
258
|
+
# interface to handle creating and inserting the test. This will occur for each instance in the current session's instance stack
|
210
259
|
#
|
211
260
|
# By default, this method will handle:
|
212
261
|
# - the placement of the test (inline aka right after the point test, end of flow, or other)
|
@@ -224,25 +273,27 @@ module OrigenTesters
|
|
224
273
|
current_id = options.delete(:id)
|
225
274
|
options[:last_test_id] ||= current_id
|
226
275
|
end
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
when :eof
|
231
|
-
# collect the current session and options into a proc, stored in eof_charz_tests to be called later
|
232
|
-
current_session = charz_session.clone
|
233
|
-
eof_charz_tests << proc do
|
234
|
-
@charz_session = current_session
|
276
|
+
charz_session.loop_instances do
|
277
|
+
case charz_instance.placement
|
278
|
+
when :inline
|
235
279
|
create_charz_group(options, &block)
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
280
|
+
when :eof
|
281
|
+
# collect the current instance and options into a proc, stored in eof_charz_tests to be called later
|
282
|
+
current_instance = charz_instance.clone
|
283
|
+
eof_charz_tests << proc do
|
284
|
+
set_charz_instance(current_instance)
|
285
|
+
create_charz_group(options, &block)
|
286
|
+
end
|
243
287
|
else
|
244
|
-
|
245
|
-
|
288
|
+
# inline is the default behavior, and eof (end of flow) has built in support.
|
289
|
+
if respond_to?(:"create_#{charz_instance.placement}_charz_tests")
|
290
|
+
send(:"create_#{charz_instance.placement}_charz_tests", options, &block)
|
291
|
+
elsif respond_to?(:"insert_#{charz_instance.placement}_charz_tests")
|
292
|
+
send(:"insert_#{charz_instance.placement}_charz_tests", options, &block)
|
293
|
+
else
|
294
|
+
Origen.log.error "No handling specified for #{charz_instance.placement} placement charz tests"
|
295
|
+
fail
|
296
|
+
end
|
246
297
|
end
|
247
298
|
end
|
248
299
|
end
|
@@ -265,9 +316,29 @@ module OrigenTesters
|
|
265
316
|
|
266
317
|
private
|
267
318
|
|
268
|
-
#
|
269
|
-
def
|
270
|
-
|
319
|
+
# helper method for charz_on and charz_on_append
|
320
|
+
def get_charz_tuple(charz_id, options)
|
321
|
+
options[:type] ||= :profile
|
322
|
+
case options[:type]
|
323
|
+
when :profile
|
324
|
+
charz_obj = charz_profiles[charz_id]
|
325
|
+
when :routine
|
326
|
+
if charz_id.is_a?(Array)
|
327
|
+
charz_obj = charz_routines[charz_id.first]
|
328
|
+
options[:routines] = charz_id
|
329
|
+
else
|
330
|
+
charz_obj = charz_routines[charz_id]
|
331
|
+
options[:routines] = [charz_id]
|
332
|
+
end
|
333
|
+
else
|
334
|
+
Origen.log.error "Unknown charz object type #{options[:type]}, valid types: :profile, :routine"
|
335
|
+
fail
|
336
|
+
end
|
337
|
+
if charz_obj.nil?
|
338
|
+
Origen.log.error "No #{options[:type]} found for charz_id: #{charz_id}"
|
339
|
+
fail
|
340
|
+
end
|
341
|
+
CharzTuple.new(obj: charz_obj, options: options, defined_routines: charz_routines.ids)
|
271
342
|
end
|
272
343
|
|
273
344
|
# called by insert_charz_tests
|
@@ -280,7 +351,7 @@ module OrigenTesters
|
|
280
351
|
if options[:skip_group]
|
281
352
|
process_on_result(options, &block)
|
282
353
|
else
|
283
|
-
group_name = options[:group_name] || "#{options[:parent_test_name]} charz #{
|
354
|
+
group_name = options[:group_name] || "#{options[:parent_test_name]} charz #{charz_instance.name}"
|
284
355
|
group group_name.to_sym do
|
285
356
|
process_on_result(options, &block)
|
286
357
|
end
|
@@ -298,8 +369,8 @@ module OrigenTesters
|
|
298
369
|
#
|
299
370
|
# @see set_conditional_charz_id
|
300
371
|
def process_on_result(options, &block)
|
301
|
-
if
|
302
|
-
case
|
372
|
+
if charz_instance.on_result
|
373
|
+
case charz_instance.on_result
|
303
374
|
when :on_fail, :fail, :failed
|
304
375
|
last_test_id = options[:last_test_id] || @last_test_id
|
305
376
|
if_failed last_test_id do
|
@@ -311,10 +382,10 @@ module OrigenTesters
|
|
311
382
|
process_gates(options, &block)
|
312
383
|
end
|
313
384
|
else
|
314
|
-
if respond_to?(:"process_#{
|
315
|
-
send(:"process_#{
|
385
|
+
if respond_to?(:"process_#{charz_instance.placement}_charz_tests")
|
386
|
+
send(:"process_#{charz_instance.on_result}_charz_tests", options, &block)
|
316
387
|
else
|
317
|
-
Origen.log.error "No handling specified for result #{
|
388
|
+
Origen.log.error "No handling specified for result #{charz_instance.on_result} charz tests"
|
318
389
|
fail
|
319
390
|
end
|
320
391
|
end
|
@@ -338,29 +409,29 @@ module OrigenTesters
|
|
338
409
|
# Pass an "and_if_true" variable for enables and flags? And use that to to decide what to do? Then we don't need 4.
|
339
410
|
# But the hash has to be structured a different way for the enable_and (routine is key, enables is value.)
|
340
411
|
def process_gates(options, &block)
|
341
|
-
if options[:skip_gates] || !(
|
342
|
-
|
412
|
+
if options[:skip_gates] || !(charz_instance.enables || charz_instance.flags)
|
413
|
+
charz_instance.routines.each do |routine|
|
343
414
|
block.call(options.merge(current_routine: routine))
|
344
415
|
end
|
345
416
|
else
|
346
|
-
if
|
347
|
-
if
|
417
|
+
if charz_instance.and_enables
|
418
|
+
if charz_instance.flags
|
348
419
|
# Wrap all tests in flag, wrap some tests in anded enables.
|
349
|
-
ungated_routines =
|
420
|
+
ungated_routines = charz_instance.routines - charz_instance.enables.keys
|
350
421
|
ungated_routines.each do |routine|
|
351
|
-
if_flag
|
422
|
+
if_flag charz_instance.flags do
|
352
423
|
block.call(options.merge(current_routine: routine))
|
353
424
|
end
|
354
425
|
end
|
355
|
-
gated_routines =
|
426
|
+
gated_routines = charz_instance.routines - ungated_routines
|
356
427
|
# Build the proc which contains the nested if statements for each routine so they are anded.
|
357
428
|
gated_routines.each do |routine|
|
358
429
|
my_proc = -> do
|
359
|
-
if_flag
|
430
|
+
if_flag charz_instance.flags do
|
360
431
|
block.call(options.merge(current_routine: routine))
|
361
432
|
end
|
362
433
|
end
|
363
|
-
|
434
|
+
charz_instance.enables[routine].inject(my_proc) do |my_block, enable|
|
364
435
|
lambda do
|
365
436
|
if_enable :"#{enable}" do
|
366
437
|
my_block.call
|
@@ -369,15 +440,15 @@ module OrigenTesters
|
|
369
440
|
end.call
|
370
441
|
end
|
371
442
|
else
|
372
|
-
ungated_routines =
|
443
|
+
ungated_routines = charz_instance.routines - charz_instance.enables.keys
|
373
444
|
ungated_routines.each do |routine|
|
374
445
|
block.call(options.merge(current_routine: routine))
|
375
446
|
end
|
376
447
|
# Build the proc which contains the nested if statements for each routine so they are anded.
|
377
|
-
gated_routines =
|
448
|
+
gated_routines = charz_instance.routines - ungated_routines
|
378
449
|
gated_routines.each do |routine|
|
379
450
|
my_proc = -> { block.call(options.merge(current_routine: routine)) }
|
380
|
-
|
451
|
+
charz_instance.enables[routine].inject(my_proc) do |my_block, enable|
|
381
452
|
lambda do
|
382
453
|
if_enable :"#{enable}" do
|
383
454
|
my_block.call
|
@@ -386,24 +457,24 @@ module OrigenTesters
|
|
386
457
|
end.call
|
387
458
|
end
|
388
459
|
end
|
389
|
-
elsif
|
390
|
-
if
|
460
|
+
elsif charz_instance.and_flags
|
461
|
+
if charz_instance.enables
|
391
462
|
# Wrap all tests in enable, some tests in anded flags.
|
392
|
-
ungated_routines =
|
463
|
+
ungated_routines = charz_instance.routines - charz_instance.flags.keys
|
393
464
|
ungated_routines.each do |routine|
|
394
|
-
if_enable
|
465
|
+
if_enable charz_instance.enables do
|
395
466
|
block.call(options.merge(current_routine: routine))
|
396
467
|
end
|
397
468
|
end
|
398
469
|
# Build the proc which contains the nested if statemements for each routine so they are anded.
|
399
|
-
gated_routines =
|
470
|
+
gated_routines = charz_instance.routines - ungated_routines
|
400
471
|
gated_routines.each do |routine|
|
401
472
|
my_proc = -> do
|
402
|
-
if_enable
|
473
|
+
if_enable charz_instance.enables do
|
403
474
|
block.call(options.merge(current_routine: routine))
|
404
475
|
end
|
405
476
|
end
|
406
|
-
|
477
|
+
charz_instance.flags[routine].inject(my_proc) do |my_block, flag|
|
407
478
|
lambda do
|
408
479
|
if_flag :"#{flag}" do
|
409
480
|
my_block.call
|
@@ -412,15 +483,15 @@ module OrigenTesters
|
|
412
483
|
end.call
|
413
484
|
end
|
414
485
|
else
|
415
|
-
ungated_routines =
|
486
|
+
ungated_routines = charz_instance.routines - charz_instance.flags.keys
|
416
487
|
ungated_routines.each do |routine|
|
417
488
|
block.call(options.merge(current_routine: routine))
|
418
489
|
end
|
419
490
|
# Build the proc which contains the nested if statemements for each routine so they are anded.
|
420
|
-
gated_routines =
|
491
|
+
gated_routines = charz_instance.routines - ungated_routines
|
421
492
|
gated_routines.each do |routine|
|
422
493
|
my_proc = -> { block.call(options.merge(current_routine: routine)) }
|
423
|
-
|
494
|
+
charz_instance.flags[routine].inject(my_proc) do |my_block, flag|
|
424
495
|
lambda do
|
425
496
|
if_flag :"#{flag}" do
|
426
497
|
my_block.call
|
@@ -429,28 +500,28 @@ module OrigenTesters
|
|
429
500
|
end.call
|
430
501
|
end
|
431
502
|
end
|
432
|
-
elsif
|
433
|
-
if
|
503
|
+
elsif charz_instance.enables && charz_instance.flags
|
504
|
+
if charz_instance.enables.is_a?(Hash) && !charz_instance.flags.is_a?(Hash)
|
434
505
|
# wrap all tests in flags, wrap specific tests in enables
|
435
|
-
if_flag
|
436
|
-
insert_hash_gates(options,
|
506
|
+
if_flag charz_instance.flags do
|
507
|
+
insert_hash_gates(options, charz_instance.enables, :if_enable, &block)
|
437
508
|
end
|
438
|
-
elsif !
|
509
|
+
elsif !charz_instance.enables.is_a?(Hash) && charz_instance.flags.is_a?(Hash)
|
439
510
|
# wrap all tests in enables, wrap specific tests in flags
|
440
|
-
if_enable
|
441
|
-
insert_hash_gates(options,
|
511
|
+
if_enable charz_instance.enables do
|
512
|
+
insert_hash_gates(options, charz_instance.flags, :if_flag, &block)
|
442
513
|
end
|
443
|
-
elsif
|
514
|
+
elsif charz_instance.enables.is_a?(Hash) && charz_instance.flags.is_a?(Hash)
|
444
515
|
# first insert the tests that are not tied to an enable or flag gate
|
445
|
-
ungated_routines =
|
516
|
+
ungated_routines = charz_instance.routines - (charz_instance.enables.values.flatten | charz_instance.flags.values.flatten)
|
446
517
|
ungated_routines.each do |routine|
|
447
518
|
block.call(options.merge(current_routine: routine))
|
448
519
|
end
|
449
520
|
# wrap tests in an enable gate, flag gate, or both
|
450
|
-
gated_routines =
|
521
|
+
gated_routines = charz_instance.routines - ungated_routines
|
451
522
|
gated_routines.each do |routine|
|
452
|
-
enable =
|
453
|
-
flag =
|
523
|
+
enable = charz_instance.enables.find { |gates, routines| routines.include?(routine) }&.first
|
524
|
+
flag = charz_instance.flags.find { |gates, routines| routines.include?(routine) }&.first
|
454
525
|
if enable && flag
|
455
526
|
if_enable enable do
|
456
527
|
if_flag flag do
|
@@ -472,9 +543,9 @@ module OrigenTesters
|
|
472
543
|
end
|
473
544
|
else
|
474
545
|
# both enable and flag is set, and both apply to all routines in session
|
475
|
-
if_enable
|
476
|
-
if_flag
|
477
|
-
|
546
|
+
if_enable charz_instance.enables do
|
547
|
+
if_flag charz_instance.flags do
|
548
|
+
charz_instance.routines.each do |routine|
|
478
549
|
block.call(options.merge(current_routine: routine))
|
479
550
|
end
|
480
551
|
end
|
@@ -482,11 +553,11 @@ module OrigenTesters
|
|
482
553
|
end
|
483
554
|
else
|
484
555
|
# only enables or flags is set, not both
|
485
|
-
if
|
486
|
-
gates =
|
556
|
+
if charz_instance.enables
|
557
|
+
gates = charz_instance.enables
|
487
558
|
gate_method = :if_enable
|
488
|
-
elsif
|
489
|
-
gates =
|
559
|
+
elsif charz_instance.flags
|
560
|
+
gates = charz_instance.flags
|
490
561
|
gate_method = :if_flag
|
491
562
|
end
|
492
563
|
if gates.is_a?(Hash)
|
@@ -495,7 +566,7 @@ module OrigenTesters
|
|
495
566
|
else
|
496
567
|
# wrap all tests in the indicated gates
|
497
568
|
send(gate_method, gates) do
|
498
|
-
|
569
|
+
charz_instance.routines.each do |routine|
|
499
570
|
block.call(options.merge(current_routine: routine))
|
500
571
|
end
|
501
572
|
end
|
@@ -507,7 +578,7 @@ module OrigenTesters
|
|
507
578
|
# helper method for the process gates method above
|
508
579
|
# handles wrapping routines in specific gates, and passing ungated routines back to the user
|
509
580
|
def insert_hash_gates(options, gate_hash, gate_method, &block)
|
510
|
-
ungated_routines =
|
581
|
+
ungated_routines = charz_instance.routines - gate_hash.values.flatten
|
511
582
|
ungated_routines.each do |routine|
|
512
583
|
block.call(options.merge(current_routine: routine))
|
513
584
|
end
|
data/program/charz.rb
CHANGED
@@ -54,11 +54,16 @@ Flow.create interface: 'OrigenTesters::Test::Interface' do
|
|
54
54
|
|
55
55
|
charz_on :complex_anded_flags, {flags: { routine1: [:my_flag1, :my_flag2]}}
|
56
56
|
func_with_charz :func_complex_anded_flags
|
57
|
+
charz_on_append :routine2, { type: :routine }
|
58
|
+
func_with_charz :func_complex_anded_flags_add_simple_rt2
|
59
|
+
charz_off_truncate
|
57
60
|
charz_off
|
58
61
|
|
59
62
|
charz_on :complex_anded_enables, {enables: { routine1: [:my_enable1, :my_enable2]}}
|
60
63
|
func_with_charz :func_complex_anded_enables
|
61
64
|
charz_off
|
62
65
|
|
66
|
+
|
67
|
+
|
63
68
|
end
|
64
69
|
end
|
@@ -79,6 +79,63 @@ add_charz_profile :anded_enables do |profile|
|
|
79
79
|
end
|
80
80
|
~~~
|
81
81
|
|
82
|
+
### Flow API
|
83
|
+
|
84
|
+
Once your profiles and routines are initialized, the primary way of using the Charz API are through charz on/off calls as well as their append/truncate counterparts:
|
85
|
+
|
86
|
+
#### charz_on / charz_off
|
87
|
+
|
88
|
+
Pushes/pops a charz object (either a profile or a routine) onto the stack, along with any optional updates to modify the current session.
|
89
|
+
Once pushed, the charz_session will attempt to update itself with the new data, failing if the resulting session is invalid. The updates will be stored as an "instance" which
|
90
|
+
is essentially a dummy Profile, and placed inside the sessions instance stack, effectively making the charz_stack a 2D array.
|
91
|
+
|
92
|
+
Once an instance is pushed onto the stack, the session becomes active and valid, allowing your apps hooks to query that state to know if a charz test needs to be inserted.
|
93
|
+
|
94
|
+
Basic Usage:
|
95
|
+
|
96
|
+
~~~ruby
|
97
|
+
# pushes the profile :my_profile onto the charz stack
|
98
|
+
charz_on :my_profile
|
99
|
+
# after you've updated your app to insert charz tests,
|
100
|
+
# this line will make two tests: point test and charz variant
|
101
|
+
func :my_test
|
102
|
+
# pops :my_profile off the charz stack
|
103
|
+
charz_off
|
104
|
+
|
105
|
+
# alternate block form, functionally identical
|
106
|
+
charz_on :my_profile do
|
107
|
+
func :my_test
|
108
|
+
end
|
109
|
+
~~~
|
110
|
+
|
111
|
+
#### charz_on_append / charz_off_truncate
|
112
|
+
|
113
|
+
Very similar to the previous charz_on/off, the append/truncate instead operates in the 2nd dimension of the 2D array that is the charz stack.
|
114
|
+
Pushes/pops a charz object (either a profile or a routine) onto the current sessions instance stack, along with any optional updates to modify that instance.
|
115
|
+
This will result in subsequent charzable point tests in being processed against each of the current instances. In other words, this new push will not take
|
116
|
+
priority over the current stack head, but instead append to it.
|
117
|
+
|
118
|
+
Basic Usage:
|
119
|
+
|
120
|
+
~~~ruby
|
121
|
+
# pushes the profile :my_profile onto the charz stack
|
122
|
+
charz_on :my_profile
|
123
|
+
# after you've updated your app to insert charz tests, this line will make two tests:
|
124
|
+
# point test and charz variant
|
125
|
+
func :my_test
|
126
|
+
# instead of pushing onto the charz stack itself,
|
127
|
+
# this will push :my_other_profile onto the instance stack of the current session,
|
128
|
+
# which is the at the head of the charz stack
|
129
|
+
charz_on_append :my_other_profile
|
130
|
+
# this line now makes 3 tests: the point test, a charz variant
|
131
|
+
# per :my_profile, and another per :my_other_profile
|
132
|
+
func :my_other_test
|
133
|
+
# pops the session of the stack, meaning both :my_profile and :my_other_profile
|
134
|
+
# are gone since they were in the same session alternately run charz_off_truncate
|
135
|
+
# to only remove :my_other_profile
|
136
|
+
charz_off
|
137
|
+
~~~
|
138
|
+
|
82
139
|
### Charz Session
|
83
140
|
|
84
141
|
The charz session (stored in your interfaces `@charz_session` attribute) monitors the current state of characterization at a given point in flow generation.
|
@@ -210,7 +267,10 @@ Where insert_current_charz_test is a method defined in the company charz flow me
|
|
210
267
|
|
211
268
|
### Flow Usage Examples
|
212
269
|
|
213
|
-
Now that the interface has charz routines and profiles, lets look at how to use the API within the flow itself
|
270
|
+
Now that the interface has charz routines and profiles, lets look at how to use the API within the flow itself. Basic usage is to make charz_on/off calls, which will set the
|
271
|
+
session to contain the called profile as the current instance to generate against.
|
272
|
+
|
273
|
+
Additionally if you would like to add additional profiles to the current session, you can use the `charz_on_append` (and its counter part: `charz_off_truncate`) to do so.
|
214
274
|
|
215
275
|
~~~ruby
|
216
276
|
Flow.create(interface: 'MyApp:Interface') do
|
@@ -235,6 +295,19 @@ Flow.create(interface: 'MyApp:Interface') do
|
|
235
295
|
func :my_test4
|
236
296
|
end
|
237
297
|
|
298
|
+
# create profileA charz test variants of my_test5, as well as profileA and profileB charz variants of my_test6
|
299
|
+
# this would produce the following tests in order:
|
300
|
+
# my_test5
|
301
|
+
# my_test5_routineA
|
302
|
+
# my_test6
|
303
|
+
# my_test6_routineA
|
304
|
+
# my_test6_routineB
|
305
|
+
charz_on :profileA do
|
306
|
+
func :my_test5
|
307
|
+
charz_on_append :profileB
|
308
|
+
func :my_test6
|
309
|
+
end
|
310
|
+
|
238
311
|
end
|
239
312
|
~~~
|
240
313
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen_testers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.51.
|
4
|
+
version: 0.51.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|