origen_testers 0.4.0
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 +7 -0
- data/config/application.rb +140 -0
- data/config/commands.rb +73 -0
- data/config/development.rb +12 -0
- data/config/environment.rb +1 -0
- data/config/shared_commands.rb +47 -0
- data/config/users.rb +18 -0
- data/config/version.rb +8 -0
- data/lib/commands/build.rb +69 -0
- data/lib/origen_testers.rb +23 -0
- data/lib/origen_testers/api.rb +258 -0
- data/lib/origen_testers/basic_test_setups.rb +105 -0
- data/lib/origen_testers/callback_handlers.rb +58 -0
- data/lib/origen_testers/generator.rb +279 -0
- data/lib/origen_testers/generator/flow_control_api.rb +611 -0
- data/lib/origen_testers/generator/identity_map.rb +23 -0
- data/lib/origen_testers/generator/placeholder.rb +11 -0
- data/lib/origen_testers/generator/test_numberer.rb +23 -0
- data/lib/origen_testers/igxl_based_tester.rb +12 -0
- data/lib/origen_testers/igxl_based_tester/base.rb +641 -0
- data/lib/origen_testers/igxl_based_tester/base/flow.rb +171 -0
- data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +322 -0
- data/lib/origen_testers/igxl_based_tester/base/generator.rb +217 -0
- data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/base/patgroups.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/patset.rb +68 -0
- data/lib/origen_testers/igxl_based_tester/base/patset_pattern.rb +56 -0
- data/lib/origen_testers/igxl_based_tester/base/patsets.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +68 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubr_pattern.rb +56 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubrs.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +326 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +58 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instances.rb +179 -0
- data/lib/origen_testers/igxl_based_tester/files.rb +43 -0
- data/lib/origen_testers/igxl_based_tester/j750.rb +248 -0
- data/lib/origen_testers/igxl_based_tester/j750/flow.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patgroups.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubrs.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/instances.txt.erb +16 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patgroups.txt.erb +8 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patsets.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patsubrs.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +547 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instances.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +34 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/flow.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/flow_line.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroups.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patset_pattern.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsets.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr_pattern.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubrs.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +515 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instances.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/parser.rb +102 -0
- data/lib/origen_testers/igxl_based_tester/parser/ac_spec.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/parser/ac_specs.rb +0 -0
- data/lib/origen_testers/igxl_based_tester/parser/dc_spec.rb +33 -0
- data/lib/origen_testers/igxl_based_tester/parser/dc_specs.rb +48 -0
- data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +339 -0
- data/lib/origen_testers/igxl_based_tester/parser/flow.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/parser/flow_line.rb +203 -0
- data/lib/origen_testers/igxl_based_tester/parser/flows.rb +21 -0
- data/lib/origen_testers/igxl_based_tester/parser/pattern_set.rb +92 -0
- data/lib/origen_testers/igxl_based_tester/parser/pattern_sets.rb +31 -0
- data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +341 -0
- data/lib/origen_testers/igxl_based_tester/parser/test_instances.rb +24 -0
- data/lib/origen_testers/igxl_based_tester/parser/timeset.rb +13 -0
- data/lib/origen_testers/igxl_based_tester/parser/timesets.rb +0 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex.rb +477 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patgroups.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patset_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubrs.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/instances.txt.erb +16 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patgroups.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsets.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsubrs.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +270 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instances.rb +10 -0
- data/lib/origen_testers/interface.rb +183 -0
- data/lib/origen_testers/parser.rb +22 -0
- data/lib/origen_testers/parser/description_lookup.rb +62 -0
- data/lib/origen_testers/parser/searchable_array.rb +30 -0
- data/lib/origen_testers/parser/searchable_hash.rb +30 -0
- data/lib/origen_testers/pattern_compilers.rb +116 -0
- data/lib/origen_testers/pattern_compilers/assembler.rb +88 -0
- data/lib/origen_testers/pattern_compilers/job.rb +96 -0
- data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +599 -0
- data/lib/origen_testers/program_generators.rb +55 -0
- data/lib/origen_testers/smartest_based_tester.rb +8 -0
- data/lib/origen_testers/smartest_based_tester/base.rb +411 -0
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +188 -0
- data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +476 -0
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +123 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +23 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +47 -0
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +143 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +73 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +43 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +166 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +58 -0
- data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +169 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -0
- data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -0
- data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +201 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -0
- data/lib/origen_testers/test/basic_interface.rb +17 -0
- data/lib/origen_testers/test/block.rb +21 -0
- data/lib/origen_testers/test/dut.rb +184 -0
- data/lib/origen_testers/test/dut2.rb +76 -0
- data/lib/origen_testers/test/j750_base_interface.rb +119 -0
- data/lib/origen_testers/test/j750_hpt_interface.rb +8 -0
- data/lib/origen_testers/test/j750_interface.rb +8 -0
- data/lib/origen_testers/test/nvm.rb +94 -0
- data/lib/origen_testers/test/ultraflex_interface.rb +110 -0
- data/lib/origen_testers/test/v93k_interface.rb +115 -0
- data/lib/origen_testers/timing.rb +362 -0
- data/lib/origen_testers/vector.rb +203 -0
- data/lib/origen_testers/vector_based_tester.rb +42 -0
- data/lib/origen_testers/vector_generator.rb +623 -0
- data/lib/origen_testers/vector_pipeline.rb +288 -0
- data/pattern/dc_instr.rb +7 -0
- data/pattern/delay.rb +7 -0
- data/pattern/mem_test.rb +8 -0
- data/pattern/multi_vector.rb +117 -0
- data/pattern/multi_vector_plus1.rb +125 -0
- data/pattern/nvm/j750/add_late_pins.rb +3 -0
- data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -0
- data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -0
- data/pattern/nvm/j750/j750_halt.rb +159 -0
- data/pattern/nvm/j750/j750_workout.rb +202 -0
- data/pattern/nvm/j750/timing.rb +73 -0
- data/pattern/nvm/v93k/v93k_workout.rb +136 -0
- data/pattern/read_write_reg.rb +58 -0
- data/pattern/reset.rb +4 -0
- data/pattern/subroutines.rb +38 -0
- data/program/_additional_erase.rb +7 -0
- data/program/_efa_resources.rb +7 -0
- data/program/_erase.rb +25 -0
- data/program/_erase_vfy.rb +5 -0
- data/program/_iv_resources.rb +10 -0
- data/program/basic_interface.rb +5 -0
- data/program/components/_prb2_main.rb +6 -0
- data/program/flow_control.rb +164 -0
- data/program/prb1.rb +226 -0
- data/program/prb1_resources.rb +28 -0
- data/program/prb2.rb +40 -0
- data/program/test.rb +20 -0
- data/templates/example.txt.erb +53 -0
- data/templates/j750/_vt_flow.txt.erb +8 -0
- data/templates/j750/_vt_instances.txt.erb +4 -0
- data/templates/j750/program_sheet.txt.erb +9 -0
- data/templates/manifest/v93k.yaml.erb +22 -0
- data/templates/web/index.md.erb +51 -0
- data/templates/web/layouts/_basic.html.erb +15 -0
- data/templates/web/partials/_navbar.html.erb +22 -0
- data/templates/web/release_notes.md.erb +5 -0
- metadata +332 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
class IGXLBasedTester
|
|
3
|
+
class Parser
|
|
4
|
+
autoload :Flows, 'origen_testers/igxl_based_tester/parser/flows'
|
|
5
|
+
autoload :Flow, 'origen_testers/igxl_based_tester/parser/flow'
|
|
6
|
+
autoload :FlowLine, 'origen_testers/igxl_based_tester/parser/flow_line'
|
|
7
|
+
autoload :TestInstances, 'origen_testers/igxl_based_tester/parser/test_instances'
|
|
8
|
+
autoload :TestInstance, 'origen_testers/igxl_based_tester/parser/test_instance'
|
|
9
|
+
autoload :PatternSets, 'origen_testers/igxl_based_tester/parser/pattern_sets'
|
|
10
|
+
autoload :PatternSet, 'origen_testers/igxl_based_tester/parser/pattern_set'
|
|
11
|
+
autoload :DCSpecs, 'origen_testers/igxl_based_tester/parser/dc_specs'
|
|
12
|
+
autoload :DCSpec, 'origen_testers/igxl_based_tester/parser/dc_spec'
|
|
13
|
+
autoload :ACSpecs, 'origen_testers/igxl_based_tester/parser/ac_specs'
|
|
14
|
+
autoload :ACSpec, 'origen_testers/igxl_based_tester/parser/ac_spec'
|
|
15
|
+
autoload :Descriptions, 'origen_testers/igxl_based_tester/parser/descriptions'
|
|
16
|
+
|
|
17
|
+
def reset
|
|
18
|
+
@flows = nil
|
|
19
|
+
@test_instances = nil
|
|
20
|
+
@pattern_sets = nil
|
|
21
|
+
@dc_specs = nil
|
|
22
|
+
@ac_specs = nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def descriptions
|
|
26
|
+
@descriptions ||= Descriptions.new(parser: self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns an array of test flows
|
|
30
|
+
def flows
|
|
31
|
+
@flows ||= Flows.new(parser: self)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_instances
|
|
35
|
+
@test_instances ||= TestInstances.new(parser: self)
|
|
36
|
+
end
|
|
37
|
+
alias_method :instances, :test_instances
|
|
38
|
+
|
|
39
|
+
def pattern_sets
|
|
40
|
+
@pattern_sets ||= PatternSets.new(parser: self)
|
|
41
|
+
end
|
|
42
|
+
alias_method :patsets, :pattern_sets
|
|
43
|
+
alias_method :pat_sets, :pattern_sets
|
|
44
|
+
|
|
45
|
+
def dc_specs
|
|
46
|
+
@dc_specs ||= DCSpecs.new(parser: self)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ac_specs
|
|
50
|
+
@ac_specs ||= ACSpecs.new(parser: self)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def inspect
|
|
54
|
+
"<Parsed Program: Flows: #{flows.size}>"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Parse a file, array of files, or a directory.
|
|
58
|
+
#
|
|
59
|
+
# This can be called multiple times to add new files to the
|
|
60
|
+
# program model.
|
|
61
|
+
def parse(file)
|
|
62
|
+
Origen.log.info ''
|
|
63
|
+
Origen.log.info "Parsing J750 test program from: #{file}"
|
|
64
|
+
Origen.log.info ''
|
|
65
|
+
reset
|
|
66
|
+
# Note use of local file handler here, this should be how it is
|
|
67
|
+
# done globally, otherwise we can run into hard to debug problems
|
|
68
|
+
# due to state/reference dir changes in the single Origen.file_handler
|
|
69
|
+
Origen::FileHandler.new.resolve_files(file) do |f|
|
|
70
|
+
parse_file(f)
|
|
71
|
+
end
|
|
72
|
+
Origen.log.info ''
|
|
73
|
+
self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def parse_file(file)
|
|
77
|
+
line = File.readlines(file).first
|
|
78
|
+
begin
|
|
79
|
+
if line =~ /Flow Table/
|
|
80
|
+
flows.import(file)
|
|
81
|
+
elsif line =~ /Instances/
|
|
82
|
+
test_instances.import(file)
|
|
83
|
+
elsif line =~ /Pattern Sets/
|
|
84
|
+
patsets.import(file)
|
|
85
|
+
elsif line =~ /DC Spec/
|
|
86
|
+
dc_specs.import(file)
|
|
87
|
+
else
|
|
88
|
+
puts "Skipped (un-supported file type): #{file}"
|
|
89
|
+
end
|
|
90
|
+
rescue Exception => e
|
|
91
|
+
if e.is_a?(ArgumentError) && e.message =~ /invalid byte sequence/
|
|
92
|
+
puts "Skipped (not ASCII): #{file}"
|
|
93
|
+
else
|
|
94
|
+
puts e.message
|
|
95
|
+
puts e.backtrace
|
|
96
|
+
exit 1
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
class IGXLBasedTester
|
|
3
|
+
class Parser
|
|
4
|
+
class DCSpec
|
|
5
|
+
attr_accessor :parser
|
|
6
|
+
attr_accessor :name, :categories
|
|
7
|
+
alias_method :symbol, :name
|
|
8
|
+
|
|
9
|
+
def initialize(name, categories, options = {})
|
|
10
|
+
@parser = options[:parser]
|
|
11
|
+
@name = name
|
|
12
|
+
@categories = categories
|
|
13
|
+
@values = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add_values(components)
|
|
17
|
+
@categories.each_with_index do |category, i|
|
|
18
|
+
@values[category] ||= {}
|
|
19
|
+
@values[category]['Typ'] ||= components[5 + (i * 3) + 0]
|
|
20
|
+
@values[category]['Min'] ||= components[5 + (i * 3) + 1]
|
|
21
|
+
@values[category]['Max'] ||= components[5 + (i * 3) + 2]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def lookup(category, selector)
|
|
26
|
+
if v == @values[category]
|
|
27
|
+
v[selector]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
class IGXLBasedTester
|
|
3
|
+
class Parser
|
|
4
|
+
class DCSpecs < ::OrigenTesters::Parser::SearchableHash
|
|
5
|
+
attr_accessor :parser
|
|
6
|
+
|
|
7
|
+
def initialize(options = {})
|
|
8
|
+
@parser = options[:parser]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def import(file)
|
|
12
|
+
@categories = []
|
|
13
|
+
File.readlines(file).each do |line|
|
|
14
|
+
unless line.strip.empty?
|
|
15
|
+
components = line.split("\t")
|
|
16
|
+
if components[3] == 'Selector'
|
|
17
|
+
extract_categories(components)
|
|
18
|
+
else
|
|
19
|
+
unless components[1] == 'DC Specs' || components[1] == 'Symbol'
|
|
20
|
+
extract_spec(components)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inspect
|
|
28
|
+
"<DCSpecs: #{size}>"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def extract_categories(components)
|
|
32
|
+
components.each_with_index do |val, i|
|
|
33
|
+
if i > 4
|
|
34
|
+
@categories << val unless val.strip.empty?
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
@categories.uniq!
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def extract_spec(components)
|
|
41
|
+
name = components[1]
|
|
42
|
+
self[name] ||= DCSpec.new(name, @categories, parser: parser)
|
|
43
|
+
self[name].add_values(components)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
class IGXLBasedTester
|
|
3
|
+
class Parser
|
|
4
|
+
# Extracts embedded test and flow descriptions (comments) from test
|
|
5
|
+
# program source files
|
|
6
|
+
class Descriptions
|
|
7
|
+
require 'fileutils'
|
|
8
|
+
|
|
9
|
+
attr_accessor :source_directories, :template_directories, :parser
|
|
10
|
+
|
|
11
|
+
SCRATCH_DIR = "#{Origen.root}/.j750_scratch"
|
|
12
|
+
|
|
13
|
+
# All descriptions are stored in this lookup table
|
|
14
|
+
def lookup
|
|
15
|
+
return @lookup if @lookup
|
|
16
|
+
# Use the one from the interface if present, program generation will
|
|
17
|
+
# automatically push descriptions in here
|
|
18
|
+
if Origen.interface_present?
|
|
19
|
+
@lookup = Origen.interface.descriptions
|
|
20
|
+
else
|
|
21
|
+
@lookup = ::OrigenTesters::Parser::DescriptionLookup.new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(options = {})
|
|
26
|
+
@parser = options[:parser]
|
|
27
|
+
FileUtils.rm_rf(SCRATCH_DIR) if File.exist?(SCRATCH_DIR)
|
|
28
|
+
parse_program
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns the description for the given flow
|
|
33
|
+
def flow_summary(options = {})
|
|
34
|
+
lookup.for_flow(options[:file])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns the description of the given test from the test
|
|
38
|
+
# instance sheet declaration
|
|
39
|
+
def test_instance(options = {})
|
|
40
|
+
lookup.for_test_definition(options[:name])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns the description of the given test from the test
|
|
44
|
+
# flow
|
|
45
|
+
def flow_line(options = {})
|
|
46
|
+
lookup.for_test_usage(options[:name], options[:flow])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def parse_program
|
|
50
|
+
Origen.file_handler.preserve_state do
|
|
51
|
+
generate_program_files
|
|
52
|
+
# Comments must be extracted manually for any compiled files, for
|
|
53
|
+
# generated files the comments will already be in the lookup
|
|
54
|
+
extract_flow_summaries
|
|
55
|
+
extract_test_instance_descriptions
|
|
56
|
+
extract_flow_line_descriptions
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def source_directories
|
|
61
|
+
[@source_directories, Origen.config.test_program_source_directory].compact.flatten
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def template_directories
|
|
65
|
+
[@template_directories, Origen.config.test_program_template_directory].compact.flatten
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def extract_flow_summaries
|
|
69
|
+
Origen.file_handler.resolve_files(compiled_dir) do |file|
|
|
70
|
+
if flow_file?(file)
|
|
71
|
+
lookup.add_for_flow(file, parse_flow_summary(file))
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Parses a compiled template for marked up comments
|
|
77
|
+
def extract_test_instance_descriptions
|
|
78
|
+
Origen.file_handler.resolve_files(compiled_dir) do |file|
|
|
79
|
+
if instance_file?(file)
|
|
80
|
+
comments = []
|
|
81
|
+
File.readlines(file).each do |line|
|
|
82
|
+
if line =~ /^<comment>(.*)/
|
|
83
|
+
comments << Regexp.last_match[1].gsub("\r", '')
|
|
84
|
+
else
|
|
85
|
+
fields = line.split("\t")
|
|
86
|
+
unless ['Test Instances', '', 'Test Name'].include? fields[1]
|
|
87
|
+
lookup.add_for_test_definition(fields[1], comments)
|
|
88
|
+
end
|
|
89
|
+
comments = []
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def extract_flow_line_descriptions
|
|
97
|
+
Origen.file_handler.resolve_files(compiled_dir) do |file|
|
|
98
|
+
if flow_file?(file)
|
|
99
|
+
f = file.basename('.txt').to_s
|
|
100
|
+
comments = []
|
|
101
|
+
header_line = true
|
|
102
|
+
File.readlines(file).each do |line|
|
|
103
|
+
if header_line
|
|
104
|
+
header_line = false if line =~ /^\s*Label/
|
|
105
|
+
else
|
|
106
|
+
if line =~ /^<comment>(.*)/
|
|
107
|
+
comments << Regexp.last_match[1].gsub("\r", '')
|
|
108
|
+
else
|
|
109
|
+
if t = FlowLine.extract_test(line)
|
|
110
|
+
lookup.add_for_test_usage(t, file, comments)
|
|
111
|
+
end
|
|
112
|
+
comments = []
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def generate_program_files
|
|
121
|
+
a = generate_program
|
|
122
|
+
b = compile_program
|
|
123
|
+
unless a || b
|
|
124
|
+
fail 'No source or template files declared from which to parse descriptions!'
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Parses the given flow file for summary text and returns it, summary
|
|
129
|
+
# text must be the very first thing in the file.
|
|
130
|
+
# Returns an array of strings each representing a line of text.
|
|
131
|
+
def parse_flow_summary(file)
|
|
132
|
+
desc = []
|
|
133
|
+
File.readlines(file).each do |line|
|
|
134
|
+
if line =~ /%?\s*<comment>(.*)/
|
|
135
|
+
desc << Regexp.last_match[1].gsub("\r", '')
|
|
136
|
+
else
|
|
137
|
+
break
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
desc
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Generate a scratch version of the program for parsing
|
|
144
|
+
def generate_program
|
|
145
|
+
if source_directories.size > 0
|
|
146
|
+
unless @program_generated
|
|
147
|
+
Origen.log.info ''
|
|
148
|
+
Origen.log.info 'Extracting embedded comments:'
|
|
149
|
+
Origen.log.info ''
|
|
150
|
+
copy_source_files_to_scratch
|
|
151
|
+
markup_source_file_comments
|
|
152
|
+
# Compile the flow file, with Ruby comments now preserved and marked up
|
|
153
|
+
desc = Origen.app.runner.generate(program: true, patterns: ungenerated_dir, output: generated_dir,
|
|
154
|
+
check_for_changes: false, collect_stats: false, quiet: true,
|
|
155
|
+
collect_descriptions: true)
|
|
156
|
+
Origen.log.info ''
|
|
157
|
+
end
|
|
158
|
+
@program_generated = true
|
|
159
|
+
else
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Compile a scratch version of the program for parsing
|
|
165
|
+
def compile_program
|
|
166
|
+
if template_directories.size > 0
|
|
167
|
+
unless @program_compiled
|
|
168
|
+
Origen.log.info ''
|
|
169
|
+
Origen.log.info 'Extracting embedded comments:'
|
|
170
|
+
Origen.log.info ''
|
|
171
|
+
copy_templates_to_scratch
|
|
172
|
+
markup_template_comments
|
|
173
|
+
# Compile the flow file, with Ruby comments now preserved and marked up
|
|
174
|
+
Origen.app.runner.generate(compile: true, patterns: uncompiled_dir, output: compiled_dir,
|
|
175
|
+
check_for_changes: false, collect_stats: false, quiet: true)
|
|
176
|
+
Origen.log.info ''
|
|
177
|
+
end
|
|
178
|
+
@program_compiled = true
|
|
179
|
+
else
|
|
180
|
+
false
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Copy all flow and instance template files to the scratch dir
|
|
185
|
+
def copy_templates_to_scratch
|
|
186
|
+
uncompiled_dir(true)
|
|
187
|
+
template_directories.each do |dir|
|
|
188
|
+
Origen.file_handler.resolve_files(dir) do |file|
|
|
189
|
+
subdir = file.relative_path_from(Pathname.new(dir)).dirname.to_s
|
|
190
|
+
cpydir = "#{uncompiled_dir}/#{subdir}"
|
|
191
|
+
FileUtils.mkdir_p(cpydir) unless File.exist?(cpydir)
|
|
192
|
+
FileUtils.copy(file, cpydir) if flow_or_instance_file?(file)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
`chmod -R 777 #{uncompiled_dir}/*` unless Dir["#{uncompiled_dir}/*"].empty?
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Copy all flow and instance source files to the scratch dir
|
|
199
|
+
def copy_source_files_to_scratch
|
|
200
|
+
source_directories.each do |dir|
|
|
201
|
+
Origen.file_handler.resolve_files(dir) do |file|
|
|
202
|
+
subdir = file.relative_path_from(Pathname.new(dir)).dirname.to_s
|
|
203
|
+
cpydir = "#{ungenerated_dir}/#{subdir}"
|
|
204
|
+
FileUtils.mkdir_p(cpydir) unless File.exist?(cpydir)
|
|
205
|
+
FileUtils.copy(file, cpydir)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def uncompiled_dir(force_make = false)
|
|
211
|
+
@uncompiled_dir ||= "#{SCRATCH_DIR}/uncompiled"
|
|
212
|
+
if force_make
|
|
213
|
+
FileUtils.rm_rf(@uncompiled_dir) if File.exist?(@uncompiled_dir)
|
|
214
|
+
@uncompiled_dir_created = false
|
|
215
|
+
end
|
|
216
|
+
unless @uncompiled_dir_created
|
|
217
|
+
FileUtils.mkdir_p(@uncompiled_dir) unless File.exist?(@uncompiled_dir)
|
|
218
|
+
@uncompiled_dir_created = true
|
|
219
|
+
end
|
|
220
|
+
@uncompiled_dir
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def ungenerated_dir
|
|
224
|
+
@ungenerated_dir ||= "#{SCRATCH_DIR}/ungenerated"
|
|
225
|
+
unless @ungenerated_dir_created
|
|
226
|
+
FileUtils.mkdir_p(@ungenerated_dir) unless File.exist?(@ungenerated_dir)
|
|
227
|
+
@ungenerated_dir_created = true
|
|
228
|
+
end
|
|
229
|
+
@ungenerated_dir
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def compiled_dir
|
|
233
|
+
@compiled_dir ||= "#{SCRATCH_DIR}/compiled"
|
|
234
|
+
unless @compiled_dir_created
|
|
235
|
+
FileUtils.mkdir_p(@compiled_dir) unless File.exist?(@compiled_dir)
|
|
236
|
+
@compiled_dir_created = true
|
|
237
|
+
end
|
|
238
|
+
@compiled_dir
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def generated_dir
|
|
242
|
+
@generated_dir ||= "#{SCRATCH_DIR}/generated"
|
|
243
|
+
unless @generated_dir_created
|
|
244
|
+
FileUtils.mkdir_p(@generated_dir) unless File.exist?(@generated_dir)
|
|
245
|
+
@generated_dir_created = true
|
|
246
|
+
end
|
|
247
|
+
@generated_dir
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Returns true if the given file looks like a J750 flow file, works for
|
|
251
|
+
# templates to
|
|
252
|
+
def flow_or_instance_file?(file, options = {})
|
|
253
|
+
options = { flow: true,
|
|
254
|
+
instance: true
|
|
255
|
+
}.merge(options)
|
|
256
|
+
if options[:flow] && options[:instance]
|
|
257
|
+
match = 'Flow|Instances'
|
|
258
|
+
elsif options[:flow]
|
|
259
|
+
match = 'Flow'
|
|
260
|
+
else
|
|
261
|
+
match = 'Instances'
|
|
262
|
+
end
|
|
263
|
+
# Not sure the best way to determine the file type of a partial, just
|
|
264
|
+
# return true for now to play it safe
|
|
265
|
+
return true if file.basename.to_s =~ /^_/
|
|
266
|
+
File.readlines(file).each do |line|
|
|
267
|
+
begin
|
|
268
|
+
unless line =~ /^%/ || line =~ /^\s*<comment>/
|
|
269
|
+
return !!(line =~ /#{match}/)
|
|
270
|
+
end
|
|
271
|
+
rescue Exception => e
|
|
272
|
+
if e.is_a?(ArgumentError) && e.message =~ /invalid byte sequence/
|
|
273
|
+
return false
|
|
274
|
+
else
|
|
275
|
+
puts e.message
|
|
276
|
+
puts e.backtrace
|
|
277
|
+
exit 1
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def flow_file?(file)
|
|
284
|
+
flow_or_instance_file?(file, instance: false)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def instance_file?(file)
|
|
288
|
+
flow_or_instance_file?(file, flow: false)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# Substitute Ruby line comments so they are preserved by compilation
|
|
292
|
+
def markup_template_comments
|
|
293
|
+
Origen.file_handler.resolve_files(uncompiled_dir) do |file|
|
|
294
|
+
lines = File.readlines(file)
|
|
295
|
+
File.open(file, 'w') do |f|
|
|
296
|
+
lines.each do |line|
|
|
297
|
+
if line =~ /^%\s*#\s?(.*)/ # Remove single leading whitespace from comment if it exists
|
|
298
|
+
comment = Regexp.last_match[1]
|
|
299
|
+
# If comment starts with a '#-' it should be removed by compilation
|
|
300
|
+
if line =~ /^%\s*#-.*/
|
|
301
|
+
f.write line
|
|
302
|
+
# Otherwise preserve it
|
|
303
|
+
else
|
|
304
|
+
f.write "<comment>#{comment}\n"
|
|
305
|
+
end
|
|
306
|
+
else
|
|
307
|
+
f.write line
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Substitute Ruby line comments so they are preserved by generation
|
|
315
|
+
def markup_source_file_comments
|
|
316
|
+
Origen.file_handler.resolve_files(ungenerated_dir) do |file|
|
|
317
|
+
lines = File.readlines(file)
|
|
318
|
+
File.open(file, 'w') do |f|
|
|
319
|
+
lines.each do |line|
|
|
320
|
+
if line =~ /^\s*#\s?(.*)/ # Remove single leading whitespace from comment if it exists
|
|
321
|
+
comment = Regexp.last_match[1]
|
|
322
|
+
# If comment starts with a '#-' it should be removed by generation
|
|
323
|
+
if line =~ /^\s*#-.*/
|
|
324
|
+
f.write line
|
|
325
|
+
# Otherwise preserve it
|
|
326
|
+
else
|
|
327
|
+
f.write "Origen.interface.comment '#{comment}'\n"
|
|
328
|
+
end
|
|
329
|
+
else
|
|
330
|
+
f.write line
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|