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