origen_testers 0.52.10 → 0.52.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ad56d048270f5877bdd6da72571a2b4f04ad2fc045d33d61bc34f7aedd9fdf8
4
- data.tar.gz: 91032b7a9d74d80ccdf9c61e816abfd642d8b187bb5d18c79af6797f94b183e7
3
+ metadata.gz: ac538468dbd558835e04eb64cd211e17b8d2a57a7d009561d25abefb5e4156f6
4
+ data.tar.gz: 690aec14f78973db77a71f426f049705e8e3fc3cb5b5d2927717c070fe76d9fe
5
5
  SHA512:
6
- metadata.gz: 1ef803cd8aea71320aaa9885f827b6a93dc79c7bb2d281e8bde083c75b0e6f3abe2db66c1829c4b65b15f4310494da19a7d3c0ae315ad4b5911df68940b3b454
7
- data.tar.gz: 8e8f3eee5a4740b8966b816359f471eb26958b3a090260bbf105121c1394f0eaab6a70e7537c605af0d7290a7f0912de0a035ceebb7df22a86dc6f701a826653
6
+ metadata.gz: 58b87ba3e59c658a7ae97c9de2bba613b163a89408ea1def9e8b23284862486ef9361aaaf6643378a66645731ad636d28d16558a5ba288a0a297abe5b5d4e7c3
7
+ data.tar.gz: 9b3740a9e086c1f2eb48c44f4449c94879381218eb084179d5bb16b9bd9f3fe0623eafed8b8f8b321b073c73bdc8f9c6e045e4b19a2a6bdf16dc203b0438d85c
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
3
  MINOR = 52
4
- BUGFIX = 10
4
+ BUGFIX = 11
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
7
7
  end
@@ -24,6 +24,11 @@ module OrigenTesters
24
24
  def initialize(id, options, &block)
25
25
  @id = id
26
26
  @id = @id.symbolize unless id.is_a? Symbol
27
+ if Origen.interface_loaded? && Origen.interface.respond_to?(:default_valid_charz_placements)
28
+ @valid_placements = Origen.interface.default_valid_charz_placements
29
+ else
30
+ @valid_placements = [:inline, :eof]
31
+ end
27
32
  options.each { |k, v| instance_variable_set("@#{k}", v) }
28
33
  (block.arity < 1 ? (instance_eval(&block)) : block.call(self)) if block_given?
29
34
  @name ||= id
@@ -55,7 +60,6 @@ module OrigenTesters
55
60
  fail
56
61
  end
57
62
 
58
- @valid_placements ||= [:inline, :eof]
59
63
  unless @valid_placements.include? @placement
60
64
  Origen.log.error "Profile #{id}: invalid placement value, must be one of: #{@valid_placements}"
61
65
  fail
@@ -20,7 +20,11 @@ module OrigenTesters
20
20
  # @return [Boolean] whether or not to wrap eof charz tests in a group
21
21
  # @!attribute eof_charz_tests_group_name
22
22
  # @return [String, Symbol] group name to be used to for eof charz tests
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
23
+ # @!attribute default_valid_charz_placements
24
+ # @return [Array<Symbol>] (:inline, :eof) list of charz placements used when verifying a new profile is valid
25
+ attr_accessor :charz_stack, :charz_routines, :charz_profiles, :charz_session, :charz_instance,
26
+ :eof_charz_tests, :skip_group_eof_charz_tests, :eof_charz_tests_group_name,
27
+ :default_valid_charz_placements
24
28
 
25
29
  def charz_stack
26
30
  @charz_stack ||= []
@@ -38,6 +42,10 @@ module OrigenTesters
38
42
  @charz_session ||= Session.new
39
43
  end
40
44
 
45
+ def default_valid_charz_placements
46
+ @default_valid_charz_placements ||= [:inline, :eof]
47
+ end
48
+
41
49
  # If there is a current instance present, that should always be used. However when running EOF charz,
42
50
  # the instance to be used is no longer set, so instead of referencing the session, use the one that we've
43
51
  # stored already
@@ -258,6 +258,12 @@ module OrigenTesters
258
258
  options = {
259
259
  name: nil
260
260
  }.merge(options)
261
+
262
+ if !options.key?(:disable_group_on_sub_flow) &&
263
+ Origen.interface.instance_variable_get(:@disable_group_on_sub_flow)
264
+ options[:disable_group_on_sub_flow] = true
265
+ end
266
+
261
267
  file = Pathname.new(file).absolute? ? file : "#{current_dir}/#{file}"
262
268
  file = Origen.file_handler.add_rb_to(file) # add .rb to filename if missing
263
269
  orig_file = "#{file}" # capture original filename possibly without pre-pended underscore
@@ -34,14 +34,21 @@ module Origen
34
34
  if OrigenTesters::Flow.flow_comments
35
35
  top = false
36
36
  name = options[:name] || Pathname.new(file).basename('.rb').to_s.sub(/^_/, '')
37
- # Generate imports as separate sub-flow files on this platform
38
- if tester.v93k? && tester.smt8?
39
- parent, sub_flow = *_sub_flow(name, options, &block)
40
- path = sub_flow.output_file.relative_path_from(Origen.file_handler.output_directory)
41
- parent.atp.sub_flow(sub_flow.atp.raw, path: path.to_s)
37
+ import_options = Origen.generator.option_pipeline.last || {}
38
+ if import_options[:disable_group_on_sub_flow] ||
39
+ # runtime options passed to the import call take priority over Flow.create static options
40
+ (import_options[:disable_group_on_sub_flow].nil? && options[:disable_group])
41
+ _create(options, &block)
42
42
  else
43
- Origen.interface.flow.group(name, description: flow_comments) do
44
- _create(options, &block)
43
+ # Generate imports as separate sub-flow files on this platform
44
+ if tester.v93k? && tester.smt8?
45
+ parent, sub_flow = *_sub_flow(name, options, &block)
46
+ path = sub_flow.output_file.relative_path_from(Origen.file_handler.output_directory)
47
+ parent.atp.sub_flow(sub_flow.atp.raw, path: path.to_s)
48
+ else
49
+ Origen.interface.flow.group(name, description: flow_comments) do
50
+ _create(options, &block)
51
+ end
45
52
  end
46
53
  end
47
54
  else
@@ -62,6 +69,7 @@ module Origen
62
69
 
63
70
  # @api private
64
71
  def _sub_flow(name, options, &block)
72
+ Origen.interface._on_sub_flow(name, options) if Origen.interface.respond_to?(:_on_sub_flow)
65
73
  @top_level_flow ||= Origen.interface.flow
66
74
  parent = Origen.interface.flow
67
75
  # If the parent flow already has a child flow of this name then we need to generate a
@@ -113,9 +121,9 @@ module Origen
113
121
  Origen.app.reload_target!
114
122
  Origen.tester.generating = :program
115
123
  end
116
- opts = Origen.generator.option_pipeline.pop || {}
124
+ options[:sub_flow_options] = Origen.generator.option_pipeline.pop || {}
117
125
  Origen.interface.startup(options) if Origen.interface.respond_to?(:startup)
118
- interface.instance_exec(opts, &block)
126
+ interface.instance_exec(options[:sub_flow_options], &block)
119
127
  Origen.interface.shutdown(options) if Origen.interface.respond_to?(:shutdown)
120
128
  if Origen.tester.doc?
121
129
  Origen.interface.flow.stop_section
@@ -491,22 +491,29 @@ module OrigenTesters
491
491
 
492
492
  def on_loop(node, options = {})
493
493
  start = node.to_a[0]
494
- if start.is_a?(String)
494
+ if start.is_a?(String) || start.is_a?(Symbol)
495
495
  start = generate_flag_name(start)
496
496
  unless smt8?
497
497
  start = "@#{start}"
498
498
  end
499
499
  end
500
500
  stop = node.to_a[1]
501
- if stop.is_a?(String) && smt8?
501
+ if stop.is_a?(String) || stop.is_a?(Symbol)
502
502
  stop = generate_flag_name(stop)
503
- elsif stop.is_a?(String)
504
- fail 'loops with \'stop\' defined as a variable cannot be supported in the defined environments.'
503
+ if tester.smt7?
504
+ stop = "@#{stop}"
505
+ end
505
506
  end
506
507
  step = node.to_a[2]
507
508
  if smt8? && !(step == -1 || step == 1)
508
509
  fail 'SMT8 does not support steps other than -1 or 1.'
509
510
  end
511
+ if step.is_a?(String) || step.is_a?(Symbol)
512
+ step = generate_flag_name(step)
513
+ if tester.smt7?
514
+ step = "@#{step}"
515
+ end
516
+ end
510
517
  if node.to_a[3].nil?
511
518
  fail 'You must supply a loop variable name!'
512
519
  else
@@ -518,7 +525,7 @@ module OrigenTesters
518
525
  end
519
526
  # num = (stop - start) / step + 1
520
527
  # Handle increment/decrement
521
- if step < 0
528
+ if step.is_a?(Numeric) && step < 0
522
529
  compare = '>'
523
530
  incdec = "- #{step * -1}"
524
531
  else
@@ -526,7 +533,10 @@ module OrigenTesters
526
533
  incdec = "+ #{step}"
527
534
  end
528
535
  if tester.smt7?
529
- line "for #{var} = #{start}; #{var} #{compare} #{stop + step} ; #{var} = #{var} #{incdec}; do"
536
+ unless stop.is_a?(String)
537
+ stop = "#{stop + step}"
538
+ end
539
+ line "for #{var} = #{start}; #{var} #{compare} #{stop} ; #{var} = #{var} #{incdec}; do"
530
540
  line "test_number_loop_increment = #{test_num_inc}"
531
541
  line '{'
532
542
  @indent += 1
@@ -0,0 +1,5 @@
1
+ Flow.create do |options|
2
+
3
+ test :"#{options[:status]}_#{options[:type]}"
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ Flow.create(disable_group: true) do |options|
2
+
3
+ test :"#{options[:status]}_#{options[:type]}"
4
+
5
+ end
data/program/prb1.rb CHANGED
@@ -19,5 +19,10 @@ Flow.create interface: 'OrigenTesters::Test::Interface', flow_description: 'Prob
19
19
  # Test that a reference to a deeply nested test works (mainly for SMT8)
20
20
  test :on_deep_1, if_failed: :deep_test, test_text: "some_custom_text"
21
21
 
22
+ import 'components/default_group_import', type: 'import_option_disable', disable_group_on_sub_flow: true, status: :ungrouped
23
+ import 'components/default_no_group_import', type: 'flow_create_option_disable', status: :ungrouped
24
+ import 'components/default_no_group_import', type: 'flow_create_option_override', disable_group_on_sub_flow: false, status: :grouped
25
+
26
+
22
27
  pass 1, description: "Good die!", softbin: 1
23
28
  end
@@ -311,4 +311,87 @@ Flow.create(interface: 'MyApp:Interface') do
311
311
  end
312
312
  ~~~
313
313
 
314
+ #### Custom Placement Example
315
+
316
+ For an example of adding new placements lets say we want to insert a charz test if the parent
317
+ test fails, but not until after a later test in the flow "testB" has ran. To do so:
318
+
319
+ * The profile needs to know that this new placement is valid and then target it
320
+ * The charz tests themselves need a placement specific constructor method that collects the results for later use
321
+ * Lastly, a method for calling the collected constructors and inserting them into the flow
322
+
323
+ ##### Adding valid placements
324
+
325
+ To add new valid placements, you can do so either on a per-profile basis or across all profiles
326
+ for the current interface:
327
+
328
+ ~~~ruby
329
+ # Per-Profile
330
+ add_charz_profile :my_profile |p|
331
+ # ...
332
+ p.valid_placements = [:on_fail_after_testB]
333
+ p.placement = :on_fail_after_testB
334
+ end
335
+
336
+ # Across Interface via interface instance variable:
337
+ @default_valid_charz_placements = [:inline, :eof, :on_fail_after_testB]
338
+
339
+ add_charz_profile :my_profile |p|
340
+ # ...
341
+ p.placement = :on_fail_after_testB
342
+ end
343
+ ~~~
344
+
345
+ ##### Placement Constructor and Collection
346
+
347
+ So that the charz API knows how to handle this placement, it will expect a method to be defined
348
+ named as `create_<placement>_charz_tests(options, &block)`. This method will need to store the
349
+ current context in a manner that can be called later. To collect multiple tests, we'll use
350
+ an interface instance variable.
351
+
352
+ ~~~ruby
353
+ # collect the current instance and options into a proc,
354
+ # which will be stored in @on_fail_after_testB_charz_tests to be called later
355
+ def create_on_fail_after_testB_charz_tests(options, &block)
356
+ # we'll need to save the current charz instance as it is now as its used in the test creation
357
+ current_instance = charz_instance.clone
358
+
359
+ # Store the setup instructions in a proc to be called later
360
+ @on_fail_after_testB_charz_tests ||= []
361
+ @on_fail_after_testB_charz_tests << proc do
362
+ # these are existing methods in the charz API
363
+ set_charz_instance(current_instance)
364
+ create_charz_group(options, &block)
365
+ end
366
+ end
367
+ ~~~
368
+
369
+ ##### Inserting collected tests into the flow
370
+
371
+ Now all thats left is to define the generator to call the collected tests, then
372
+ we can apply our charz profile to the tests of interest and call the generator after testB
373
+ has ran.
374
+
375
+ ~~~ruby
376
+ # simple generator to call each collected proc
377
+ def generate_on_fail_after_testB_charz_tests
378
+ @on_fail_after_testB_charz_tests.map(&:call)
379
+ @on_fail_after_testB_charz_tests = [] # clear to prevent accidental repeats
380
+ end
381
+ ~~~
382
+
383
+ And then finally in the flow:
384
+
385
+ ~~~ruby
386
+ charz_on :my_profile do
387
+ func :test_i_want_to_charz1, id: :t1
388
+ func :test_i_want_to_charz2, id: :t2
389
+ end
390
+
391
+ # ...
392
+
393
+ func :testB
394
+ generate_on_fail_after_testB_charz_tests
395
+ ~~~
396
+
314
397
  % end
@@ -406,8 +406,6 @@ Decrementing loops, having `from:` value > `to:` value and using negative `step:
406
406
 
407
407
  ##### Loop Rules For Each Environment
408
408
 
409
- `SMT7` cannot support a variable stop location. Only the `from:` parameter is allowed to be a variable.
410
-
411
409
  `SMT8` cannot have a step other than -1 or 1. The limitations of the range flow restrict those steps.
412
410
  The `to:` parameter can be a flow variable just like `from:`.
413
411
 
@@ -110,6 +110,38 @@ end
110
110
 
111
111
  This same API may be used to implement similar features on other platforms in future, but for now only the V93K is implemented.
112
112
 
113
+ #### Grouping on sub-flows
114
+
115
+ By default, imported sub-flows are wrapped in a group named by the passed `:name` option if provided, otherwise the name of the file is used.
116
+
117
+ ~~~ruby
118
+ import 'my_sub_flow' # sub flow contains single test 'my_test'
119
+
120
+ # Results in the following output in the .tf file:
121
+ # {
122
+ # run(my_test);
123
+ # }, open,"my_sub_flow", ""
124
+ ~~~
125
+
126
+ To disable this behavior, you can either pass to your import call the option `disable_group_on_sub_flow: true`,
127
+ or set `disable_group: true` in your Flow.create() parameters:
128
+
129
+ ~~~ruby
130
+ # Pass option to import
131
+ import 'my_sub_flow', { disable_group_on_sub_flow: true }
132
+
133
+ # Or set in Flow.create() in _my_sub_flow.rb
134
+ Flow.create(disable_group: true) do
135
+ func :my_test
136
+ end
137
+
138
+ # Results in the following output in the .tf file:
139
+ # run(my_test);
140
+ ~~~
141
+
142
+ Note that the import option takes priority, so if `Flow.create(disable_group: true)`
143
+ is set but import is passed `disable_group_on_sub_flow: false` then a group will still be created.
144
+
113
145
  ### Test Name Uniqueness
114
146
 
115
147
  Test (suite) naming collisions can occur when importing multiple independent test flow modules into a
@@ -55,7 +55,11 @@ Contains the limits tables for all flows.
55
55
  A top-level test program flow file in Origen will generate a correspondingly named file in the `flows/` directory,
56
56
  where the name of the generated file is the upper-cased version of the source file name.
57
57
  If the flow imports sub-flows or contains groups, then those will be contained in a directory named after the
58
- lower-cased version of the flow name.
58
+ lower-cased version of the flow name. For sub-flow imports, this can be disabled by passing the option
59
+ `disable_sub_flow_on_group: true` to the import call, or by setting the disable_group option in your sub-flow:
60
+ `Flow.create(disable_group: true)`. Note that if both are provided, the import option value will take priority.
61
+ When the group is disabled this way, the content of the sub-flow will simply be inserted as if it was defined
62
+ in the calling flow instead of a sub flow.
59
63
 
60
64
  ##### limits/
61
65
 
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.52.10
4
+ version: 0.52.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-20 00:00:00.000000000 Z
11
+ date: 2025-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -170,7 +170,7 @@ dependencies:
170
170
  - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: '1.24'
173
- description:
173
+ description:
174
174
  email:
175
175
  - stephen.f.mcginty@gmail.com
176
176
  executables: []
@@ -542,6 +542,8 @@ files:
542
542
  - program/basic_interface.rb
543
543
  - program/charz.rb
544
544
  - program/components/_deep_nested.rb
545
+ - program/components/_default_group_import.rb
546
+ - program/components/_default_no_group_import.rb
545
547
  - program/components/_prb1_main.rb
546
548
  - program/components/_prb2_main.rb
547
549
  - program/components/_small.rb
@@ -603,7 +605,7 @@ files:
603
605
  homepage: http://origen-sdk.org/testers
604
606
  licenses: []
605
607
  metadata: {}
606
- post_install_message:
608
+ post_install_message:
607
609
  rdoc_options: []
608
610
  require_paths:
609
611
  - lib
@@ -619,7 +621,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
619
621
  version: '0'
620
622
  requirements: []
621
623
  rubygems_version: 3.1.6
622
- signing_key:
624
+ signing_key:
623
625
  specification_version: 4
624
626
  summary: This plugin provides Origen tester models to drive ATE type testers like
625
627
  the J750, UltraFLEX, V93K,...