origen_testers 0.51.1 → 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 +70 -3
- data/lib/origen_testers/charz/session.rb +127 -50
- data/lib/origen_testers/charz.rb +240 -80
- data/lib/origen_testers/test/interface.rb +22 -0
- data/program/charz.rb +30 -9
- data/templates/origen_guides/program/charz.md.erb +95 -2
- metadata +3 -3
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
|
|
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?
|
|
@@ -74,8 +75,34 @@ module OrigenTesters
|
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
unless @gate_checks == false
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
if @and_enables && @and_flags
|
|
79
|
+
Origen.log.error "@and_enables and @and_flags are both set to true. Please only 'and' one gate type"
|
|
80
|
+
fail
|
|
81
|
+
end
|
|
82
|
+
if @and_enables
|
|
83
|
+
gate_check(@flags, :flags) if @flags
|
|
84
|
+
gate_check_and(@enables, :enables, @flags) if @enables
|
|
85
|
+
elsif @and_flags
|
|
86
|
+
gate_check(@enables, :enables) if @enables
|
|
87
|
+
gate_check_and(@flags, :flags, @enables) if @flags
|
|
88
|
+
else
|
|
89
|
+
gate_check(@enables, :enable) if @enables
|
|
90
|
+
gate_check(@flags, :flags) if @flags
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
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
|
|
79
106
|
end
|
|
80
107
|
end
|
|
81
108
|
|
|
@@ -112,6 +139,46 @@ module OrigenTesters
|
|
|
112
139
|
end
|
|
113
140
|
end
|
|
114
141
|
|
|
142
|
+
def gate_check_and(gates, gate_type, other_gate)
|
|
143
|
+
if other_gate.is_a? Hash
|
|
144
|
+
Origen.log.error "Profile #{id}: #{other_gate} When using &&-ing feature, the non-anded gate can not be of type hash."
|
|
145
|
+
fail
|
|
146
|
+
end
|
|
147
|
+
case gates
|
|
148
|
+
when Symbol, String
|
|
149
|
+
return
|
|
150
|
+
when Array
|
|
151
|
+
unknown_gates = gates.reject { |gate| [String, Symbol].include? gate.class }
|
|
152
|
+
if unknown_gates.empty?
|
|
153
|
+
return
|
|
154
|
+
else
|
|
155
|
+
Origen.log.error "Profile #{id}: Unknown #{gate_type} type(s) in #{gate_type} array."
|
|
156
|
+
Origen.log.error "Arrays must contain Strings and/or Symbols, but #{unknown_gates.map(&:class).uniq } were found in #{gates}"
|
|
157
|
+
fail
|
|
158
|
+
end
|
|
159
|
+
when Hash
|
|
160
|
+
gates.each do |gated_routine, gates|
|
|
161
|
+
if gated_routine.is_a? Hash
|
|
162
|
+
Origen.log.error "Profile #{id}: #{gate_type} Hash keys cannot be of type Hash, but only Symbol, String, or Array"
|
|
163
|
+
fail
|
|
164
|
+
end
|
|
165
|
+
unless @defined_routines.include?(gated_routine)
|
|
166
|
+
Origen.log.error "Profile #{id}: #{gated_routine} Hash keys for &&-ed gates must be defined routines."
|
|
167
|
+
fail
|
|
168
|
+
end
|
|
169
|
+
gates = [gates] unless gates.is_a? Array
|
|
170
|
+
unknown_gates = gates.reject { |gate| [String, Symbol].include? gate.class }
|
|
171
|
+
unless unknown_gates.empty?
|
|
172
|
+
Origen.log.error "Gate array must contain Strings and/or Symbols, but #{unknown_gates.map(&:class).uniq } were found in #{gates}"
|
|
173
|
+
fail
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
Origen.log.error "Profile #{id}: Unknown #{gate_type} type: #{gates.class}. #{gate_type} must be of type Symbol, String, Array, or Hash"
|
|
178
|
+
fail
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
115
182
|
def method_missing(m, *args, &block)
|
|
116
183
|
ivar = "@#{m.to_s.gsub('=', '')}"
|
|
117
184
|
ivar_sym = ":#{ivar}"
|
|
@@ -1,29 +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
|
-
|
|
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?
|
|
27
57
|
end
|
|
28
58
|
|
|
29
59
|
# Pauses the current session's activity while maintaining everthing else about the sessions state
|
|
@@ -31,6 +61,11 @@ module OrigenTesters
|
|
|
31
61
|
@active = false
|
|
32
62
|
end
|
|
33
63
|
|
|
64
|
+
def active?
|
|
65
|
+
!!@active
|
|
66
|
+
end
|
|
67
|
+
alias_method :active, :active?
|
|
68
|
+
|
|
34
69
|
# Resume activity, if the session is valid
|
|
35
70
|
def resume
|
|
36
71
|
if @valid
|
|
@@ -38,61 +73,103 @@ module OrigenTesters
|
|
|
38
73
|
end
|
|
39
74
|
end
|
|
40
75
|
|
|
41
|
-
|
|
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
|
|
42
94
|
# the attributes values can be set from 3 different sources, in order of priority (first is most important):
|
|
43
95
|
# - options
|
|
44
|
-
# - charz object
|
|
96
|
+
# - charz object (Profile or Routine)
|
|
45
97
|
# - defaults
|
|
46
98
|
#
|
|
47
99
|
# If the resulting session is invalid, @valid will turn false. Otherwise, the session becomes active
|
|
48
|
-
def update(
|
|
100
|
+
def update(charz_tuples)
|
|
101
|
+
@instances = []
|
|
49
102
|
@valid = false
|
|
50
|
-
if
|
|
103
|
+
if charz_tuples.nil? || charz_tuples.empty?
|
|
51
104
|
@active = false
|
|
52
105
|
@valid = false
|
|
106
|
+
@current_instance = nil
|
|
53
107
|
return @valid
|
|
54
108
|
end
|
|
55
|
-
@defined_routines =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
assign_by_priority(:charz_only, charz_obj, options)
|
|
63
|
-
attrs_ok?
|
|
64
|
-
massage_gates
|
|
109
|
+
@defined_routines = charz_tuples.map(&:defined_routines).flatten.uniq.compact
|
|
110
|
+
|
|
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))
|
|
114
|
+
end
|
|
115
|
+
@id = instances.map(&:id).join('_').to_sym
|
|
65
116
|
@active = true
|
|
66
117
|
@valid = true
|
|
67
118
|
end
|
|
68
119
|
|
|
69
120
|
private
|
|
70
121
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
81
136
|
end
|
|
82
137
|
end
|
|
138
|
+
instance_options
|
|
83
139
|
end
|
|
84
140
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
|
93
171
|
else
|
|
94
|
-
|
|
95
|
-
fail
|
|
172
|
+
super
|
|
96
173
|
end
|
|
97
174
|
end
|
|
98
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
|
|
@@ -334,34 +405,123 @@ module OrigenTesters
|
|
|
334
405
|
#
|
|
335
406
|
# This is the final method of handling the insert_charz_test usecases, where the block thats been passed around is finally called
|
|
336
407
|
# the user's provided block is passed the current routine (one at a time) to then take its info to generate a charz test
|
|
408
|
+
|
|
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.
|
|
410
|
+
# But the hash has to be structured a different way for the enable_and (routine is key, enables is value.)
|
|
337
411
|
def process_gates(options, &block)
|
|
338
|
-
if options[:skip_gates] || !(
|
|
339
|
-
|
|
412
|
+
if options[:skip_gates] || !(charz_instance.enables || charz_instance.flags)
|
|
413
|
+
charz_instance.routines.each do |routine|
|
|
340
414
|
block.call(options.merge(current_routine: routine))
|
|
341
415
|
end
|
|
342
416
|
else
|
|
343
|
-
if
|
|
344
|
-
if
|
|
417
|
+
if charz_instance.and_enables
|
|
418
|
+
if charz_instance.flags
|
|
419
|
+
# Wrap all tests in flag, wrap some tests in anded enables.
|
|
420
|
+
ungated_routines = charz_instance.routines - charz_instance.enables.keys
|
|
421
|
+
ungated_routines.each do |routine|
|
|
422
|
+
if_flag charz_instance.flags do
|
|
423
|
+
block.call(options.merge(current_routine: routine))
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
gated_routines = charz_instance.routines - ungated_routines
|
|
427
|
+
# Build the proc which contains the nested if statements for each routine so they are anded.
|
|
428
|
+
gated_routines.each do |routine|
|
|
429
|
+
my_proc = -> do
|
|
430
|
+
if_flag charz_instance.flags do
|
|
431
|
+
block.call(options.merge(current_routine: routine))
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
charz_instance.enables[routine].inject(my_proc) do |my_block, enable|
|
|
435
|
+
lambda do
|
|
436
|
+
if_enable :"#{enable}" do
|
|
437
|
+
my_block.call
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end.call
|
|
441
|
+
end
|
|
442
|
+
else
|
|
443
|
+
ungated_routines = charz_instance.routines - charz_instance.enables.keys
|
|
444
|
+
ungated_routines.each do |routine|
|
|
445
|
+
block.call(options.merge(current_routine: routine))
|
|
446
|
+
end
|
|
447
|
+
# Build the proc which contains the nested if statements for each routine so they are anded.
|
|
448
|
+
gated_routines = charz_instance.routines - ungated_routines
|
|
449
|
+
gated_routines.each do |routine|
|
|
450
|
+
my_proc = -> { block.call(options.merge(current_routine: routine)) }
|
|
451
|
+
charz_instance.enables[routine].inject(my_proc) do |my_block, enable|
|
|
452
|
+
lambda do
|
|
453
|
+
if_enable :"#{enable}" do
|
|
454
|
+
my_block.call
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
end.call
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
elsif charz_instance.and_flags
|
|
461
|
+
if charz_instance.enables
|
|
462
|
+
# Wrap all tests in enable, some tests in anded flags.
|
|
463
|
+
ungated_routines = charz_instance.routines - charz_instance.flags.keys
|
|
464
|
+
ungated_routines.each do |routine|
|
|
465
|
+
if_enable charz_instance.enables do
|
|
466
|
+
block.call(options.merge(current_routine: routine))
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
# Build the proc which contains the nested if statemements for each routine so they are anded.
|
|
470
|
+
gated_routines = charz_instance.routines - ungated_routines
|
|
471
|
+
gated_routines.each do |routine|
|
|
472
|
+
my_proc = -> do
|
|
473
|
+
if_enable charz_instance.enables do
|
|
474
|
+
block.call(options.merge(current_routine: routine))
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
charz_instance.flags[routine].inject(my_proc) do |my_block, flag|
|
|
478
|
+
lambda do
|
|
479
|
+
if_flag :"#{flag}" do
|
|
480
|
+
my_block.call
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
end.call
|
|
484
|
+
end
|
|
485
|
+
else
|
|
486
|
+
ungated_routines = charz_instance.routines - charz_instance.flags.keys
|
|
487
|
+
ungated_routines.each do |routine|
|
|
488
|
+
block.call(options.merge(current_routine: routine))
|
|
489
|
+
end
|
|
490
|
+
# Build the proc which contains the nested if statemements for each routine so they are anded.
|
|
491
|
+
gated_routines = charz_instance.routines - ungated_routines
|
|
492
|
+
gated_routines.each do |routine|
|
|
493
|
+
my_proc = -> { block.call(options.merge(current_routine: routine)) }
|
|
494
|
+
charz_instance.flags[routine].inject(my_proc) do |my_block, flag|
|
|
495
|
+
lambda do
|
|
496
|
+
if_flag :"#{flag}" do
|
|
497
|
+
my_block.call
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
end.call
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
elsif charz_instance.enables && charz_instance.flags
|
|
504
|
+
if charz_instance.enables.is_a?(Hash) && !charz_instance.flags.is_a?(Hash)
|
|
345
505
|
# wrap all tests in flags, wrap specific tests in enables
|
|
346
|
-
if_flag
|
|
347
|
-
insert_hash_gates(options,
|
|
506
|
+
if_flag charz_instance.flags do
|
|
507
|
+
insert_hash_gates(options, charz_instance.enables, :if_enable, &block)
|
|
348
508
|
end
|
|
349
|
-
elsif !
|
|
509
|
+
elsif !charz_instance.enables.is_a?(Hash) && charz_instance.flags.is_a?(Hash)
|
|
350
510
|
# wrap all tests in enables, wrap specific tests in flags
|
|
351
|
-
if_enable
|
|
352
|
-
insert_hash_gates(options,
|
|
511
|
+
if_enable charz_instance.enables do
|
|
512
|
+
insert_hash_gates(options, charz_instance.flags, :if_flag, &block)
|
|
353
513
|
end
|
|
354
|
-
elsif
|
|
514
|
+
elsif charz_instance.enables.is_a?(Hash) && charz_instance.flags.is_a?(Hash)
|
|
355
515
|
# first insert the tests that are not tied to an enable or flag gate
|
|
356
|
-
ungated_routines =
|
|
516
|
+
ungated_routines = charz_instance.routines - (charz_instance.enables.values.flatten | charz_instance.flags.values.flatten)
|
|
357
517
|
ungated_routines.each do |routine|
|
|
358
518
|
block.call(options.merge(current_routine: routine))
|
|
359
519
|
end
|
|
360
520
|
# wrap tests in an enable gate, flag gate, or both
|
|
361
|
-
gated_routines =
|
|
521
|
+
gated_routines = charz_instance.routines - ungated_routines
|
|
362
522
|
gated_routines.each do |routine|
|
|
363
|
-
enable =
|
|
364
|
-
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
|
|
365
525
|
if enable && flag
|
|
366
526
|
if_enable enable do
|
|
367
527
|
if_flag flag do
|
|
@@ -383,9 +543,9 @@ module OrigenTesters
|
|
|
383
543
|
end
|
|
384
544
|
else
|
|
385
545
|
# both enable and flag is set, and both apply to all routines in session
|
|
386
|
-
if_enable
|
|
387
|
-
if_flag
|
|
388
|
-
|
|
546
|
+
if_enable charz_instance.enables do
|
|
547
|
+
if_flag charz_instance.flags do
|
|
548
|
+
charz_instance.routines.each do |routine|
|
|
389
549
|
block.call(options.merge(current_routine: routine))
|
|
390
550
|
end
|
|
391
551
|
end
|
|
@@ -393,11 +553,11 @@ module OrigenTesters
|
|
|
393
553
|
end
|
|
394
554
|
else
|
|
395
555
|
# only enables or flags is set, not both
|
|
396
|
-
if
|
|
397
|
-
gates =
|
|
556
|
+
if charz_instance.enables
|
|
557
|
+
gates = charz_instance.enables
|
|
398
558
|
gate_method = :if_enable
|
|
399
|
-
elsif
|
|
400
|
-
gates =
|
|
559
|
+
elsif charz_instance.flags
|
|
560
|
+
gates = charz_instance.flags
|
|
401
561
|
gate_method = :if_flag
|
|
402
562
|
end
|
|
403
563
|
if gates.is_a?(Hash)
|
|
@@ -406,7 +566,7 @@ module OrigenTesters
|
|
|
406
566
|
else
|
|
407
567
|
# wrap all tests in the indicated gates
|
|
408
568
|
send(gate_method, gates) do
|
|
409
|
-
|
|
569
|
+
charz_instance.routines.each do |routine|
|
|
410
570
|
block.call(options.merge(current_routine: routine))
|
|
411
571
|
end
|
|
412
572
|
end
|
|
@@ -418,7 +578,7 @@ module OrigenTesters
|
|
|
418
578
|
# helper method for the process gates method above
|
|
419
579
|
# handles wrapping routines in specific gates, and passing ungated routines back to the user
|
|
420
580
|
def insert_hash_gates(options, gate_hash, gate_method, &block)
|
|
421
|
-
ungated_routines =
|
|
581
|
+
ungated_routines = charz_instance.routines - gate_hash.values.flatten
|
|
422
582
|
ungated_routines.each do |routine|
|
|
423
583
|
block.call(options.merge(current_routine: routine))
|
|
424
584
|
end
|
|
@@ -50,6 +50,28 @@ module OrigenTesters
|
|
|
50
50
|
profile.enables = { ['$MyEnable1'] => [:routine1], ['$MyEnable2'] => [:routine2, :routine3], '$MyEnable3' => :routine5 }
|
|
51
51
|
profile.routines = [:routine1, :routine2, :routine3, :routine4, :routine5, :routine6]
|
|
52
52
|
end
|
|
53
|
+
|
|
54
|
+
add_charz_profile :simple_anded_flags do |profile|
|
|
55
|
+
profile.and_flags = true
|
|
56
|
+
profile.routines = [:routine1]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
add_charz_profile :simple_anded_enables do |profile|
|
|
60
|
+
profile.and_enables = true
|
|
61
|
+
profile.routines = [:routine1]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
add_charz_profile :complex_anded_flags do |profile|
|
|
65
|
+
profile.and_flags = true
|
|
66
|
+
profile.enables = :my_enable
|
|
67
|
+
profile.routines = [:routine1]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
add_charz_profile :complex_anded_enables do |profile|
|
|
71
|
+
profile.and_enables = true
|
|
72
|
+
profile.flags = :my_flag
|
|
73
|
+
profile.routines = [:routine1]
|
|
74
|
+
end
|
|
53
75
|
end
|
|
54
76
|
|
|
55
77
|
# Test that the block form of flow control methods like this can
|
data/program/charz.rb
CHANGED
|
@@ -7,11 +7,11 @@ Flow.create interface: 'OrigenTesters::Test::Interface' do
|
|
|
7
7
|
|
|
8
8
|
if tester.v93k? && tester.smt7?
|
|
9
9
|
charz_on :complex_gates, { on_result: :fail }
|
|
10
|
-
|
|
10
|
+
func_with_charz :func_complex_gates_on_fail
|
|
11
11
|
charz_off
|
|
12
12
|
|
|
13
13
|
charz_on :complex_gates, { enables: :my_enable }
|
|
14
|
-
|
|
14
|
+
func_with_charz :func_complex_flag_simple_enable
|
|
15
15
|
charz_off
|
|
16
16
|
|
|
17
17
|
charz_on :complex_gates, { flags: :my_flag } do
|
|
@@ -19,17 +19,17 @@ Flow.create interface: 'OrigenTesters::Test::Interface' do
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
charz_on :cz_only, { placement: :eof }
|
|
22
|
-
|
|
22
|
+
func_with_charz :func_charz_only
|
|
23
23
|
charz_off
|
|
24
24
|
|
|
25
25
|
func_with_charz :func_test_level_routine, charz: [:routine1, { type: :routine }]
|
|
26
26
|
|
|
27
27
|
charz_on :cz
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
func_with_charz :func_skip_group, skip_group: true
|
|
29
|
+
charz_pause
|
|
30
|
+
func_with_charz :func_pause_charz
|
|
31
|
+
charz_resume
|
|
32
|
+
func_with_charz :func_resume_charz
|
|
33
33
|
charz_off
|
|
34
34
|
|
|
35
35
|
charz_on :simple_gates, { on_result: :pass } do
|
|
@@ -43,6 +43,27 @@ Flow.create interface: 'OrigenTesters::Test::Interface' do
|
|
|
43
43
|
charz_on :simple_gates, { flags: nil }
|
|
44
44
|
func_with_charz :func_simple_enables
|
|
45
45
|
charz_off
|
|
46
|
-
end
|
|
47
46
|
|
|
47
|
+
charz_on :simple_anded_flags, { flags: { routine1: [:my_flag1, :my_flag2]}}
|
|
48
|
+
func_with_charz :func_simple_anded_flags
|
|
49
|
+
charz_off
|
|
50
|
+
|
|
51
|
+
charz_on :simple_anded_enables, {enables: { routine1: [:my_enable1, :my_enable2]}}
|
|
52
|
+
func_with_charz :func_simple_anded_enables
|
|
53
|
+
charz_off
|
|
54
|
+
|
|
55
|
+
charz_on :complex_anded_flags, {flags: { routine1: [:my_flag1, :my_flag2]}}
|
|
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
|
|
60
|
+
charz_off
|
|
61
|
+
|
|
62
|
+
charz_on :complex_anded_enables, {enables: { routine1: [:my_enable1, :my_enable2]}}
|
|
63
|
+
func_with_charz :func_complex_anded_enables
|
|
64
|
+
charz_off
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
end
|
|
48
69
|
end
|
|
@@ -48,7 +48,7 @@ end
|
|
|
48
48
|
Charz profiles contain a collection of routines, as well as test creation meta data related to test placement, production test result dependence, and conditional execution.
|
|
49
49
|
|
|
50
50
|
The interface adds charz profiles by calling the `add_charz_profile` method. To create a profile that contains previously defined vmin and vmax search routines, whose resulting searches
|
|
51
|
-
only run if the production test failed, and sets the vmax search routine to only run if the 'VmaxEnable' variable is set
|
|
51
|
+
only run if the production test failed, and sets the vmax search routine to only run if the 'VmaxEnable' variable is set.
|
|
52
52
|
|
|
53
53
|
~~~ruby
|
|
54
54
|
add_charz_profile :fail_searches do |profile|
|
|
@@ -59,6 +59,83 @@ add_charz_profile :fail_searches do |profile|
|
|
|
59
59
|
end
|
|
60
60
|
~~~
|
|
61
61
|
|
|
62
|
+
The default behavior for gates is to "OR" them if multiple are defined. The below will result in each routine being nested inside 'my_enable1 or my_enable2'.
|
|
63
|
+
~~~ruby
|
|
64
|
+
add_charz_profile :enables do |profile|
|
|
65
|
+
profile.name = 'enables'
|
|
66
|
+
profile.routines = [:vmin, :vmax]
|
|
67
|
+
profile.enables = [:my_enable1, :my_enable2]
|
|
68
|
+
end
|
|
69
|
+
~~~
|
|
70
|
+
|
|
71
|
+
The profile can be updated to "AND" together multiple enables or flags. To set up this functionality
|
|
72
|
+
create a hash which maps a routine name to multiple flags and set the corresponding "and_" profile attribute to true.
|
|
73
|
+
~~~ruby
|
|
74
|
+
add_charz_profile :anded_enables do |profile|
|
|
75
|
+
profile.name = 'anded_enables'
|
|
76
|
+
profile.routines = [:vmin, :vmax]
|
|
77
|
+
profile.and_enables = true
|
|
78
|
+
profile.enables = { vmin: [:overall_enable, :vmin_enable], vmax: [:overall_enable, :vmax_enable]}
|
|
79
|
+
end
|
|
80
|
+
~~~
|
|
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
|
+
|
|
62
139
|
### Charz Session
|
|
63
140
|
|
|
64
141
|
The charz session (stored in your interfaces `@charz_session` attribute) monitors the current state of characterization at a given point in flow generation.
|
|
@@ -190,7 +267,10 @@ Where insert_current_charz_test is a method defined in the company charz flow me
|
|
|
190
267
|
|
|
191
268
|
### Flow Usage Examples
|
|
192
269
|
|
|
193
|
-
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.
|
|
194
274
|
|
|
195
275
|
~~~ruby
|
|
196
276
|
Flow.create(interface: 'MyApp:Interface') do
|
|
@@ -215,6 +295,19 @@ Flow.create(interface: 'MyApp:Interface') do
|
|
|
215
295
|
func :my_test4
|
|
216
296
|
end
|
|
217
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
|
+
|
|
218
311
|
end
|
|
219
312
|
~~~
|
|
220
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
|
|
@@ -601,7 +601,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
601
601
|
- !ruby/object:Gem::Version
|
|
602
602
|
version: '0'
|
|
603
603
|
requirements: []
|
|
604
|
-
rubygems_version: 3.2.
|
|
604
|
+
rubygems_version: 3.2.3
|
|
605
605
|
signing_key:
|
|
606
606
|
specification_version: 4
|
|
607
607
|
summary: This plugin provides Origen tester models to drive ATE type testers like
|