origen_testers 0.7.9 → 0.7.10
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/version.rb +1 -1
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +16 -6
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +39 -8
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +1 -1
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +7 -0
- data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +35 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb +83 -80
- data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +48 -0
- data/lib/origen_testers/smartest_based_tester/v93k/variables_file.rb +10 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fa93b1de5dc4b7588e87bedbf2766dfde8fb16e
|
4
|
+
data.tar.gz: d1513d3d83ea18680d577f7ffab62a9ec17a6dec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12dfc6462fdeacb4d8044447b78c5144115dd711008e637bde53772ef46974b209be09f8fb6af392dd6c73ac8b75e39b4423f98b6de02de5521cfc405dab1821
|
7
|
+
data.tar.gz: 8843504728de2a0e1df34c0d2dcf95f56e8967b6e557d374656571e5348cec6896527a97e5fb9b9eaf4d7b4ffdf07a199d59340d87dd9f69265b5c349cee6293
|
data/config/version.rb
CHANGED
@@ -4,7 +4,11 @@ module OrigenTesters
|
|
4
4
|
class Flow < ATP::Formatter
|
5
5
|
include OrigenTesters::Flow
|
6
6
|
|
7
|
-
attr_accessor :test_suites, :test_methods, :lines, :stack
|
7
|
+
attr_accessor :test_suites, :test_methods, :lines, :stack, :var_filename
|
8
|
+
|
9
|
+
def var_filename
|
10
|
+
@var_filename || 'global'
|
11
|
+
end
|
8
12
|
|
9
13
|
def subdirectory
|
10
14
|
'testflow/mfh.testflow.group'
|
@@ -19,11 +23,11 @@ module OrigenTesters
|
|
19
23
|
end
|
20
24
|
|
21
25
|
def flow_control_variables
|
22
|
-
|
26
|
+
Origen.interface.variables_file(self).flow_control_variables
|
23
27
|
end
|
24
28
|
|
25
29
|
def runtime_control_variables
|
26
|
-
|
30
|
+
Origen.interface.variables_file(self).runtime_control_variables
|
27
31
|
end
|
28
32
|
|
29
33
|
def at_flow_start
|
@@ -40,14 +44,20 @@ module OrigenTesters
|
|
40
44
|
@lines = []
|
41
45
|
@stack = { on_fail: [], on_pass: [] }
|
42
46
|
process(model.ast)
|
43
|
-
flow_control_variables.uniq!
|
44
|
-
runtime_control_variables.uniq!
|
45
47
|
end
|
46
48
|
|
47
49
|
def line(str)
|
48
50
|
@lines << (' ' * @indent * 2) + str
|
49
51
|
end
|
50
52
|
|
53
|
+
# def on_flow(node)
|
54
|
+
# line '{'
|
55
|
+
# @indent += 1
|
56
|
+
# process_all(node.children)
|
57
|
+
# @indent -= 1
|
58
|
+
# line "}, open,\"#{unique_group_name(node.find(:name).value)}\", \"\""
|
59
|
+
# end
|
60
|
+
|
51
61
|
def on_test(node)
|
52
62
|
name = node.find(:object).to_a[0]
|
53
63
|
name = name.name unless name.is_a?(String)
|
@@ -84,7 +94,7 @@ module OrigenTesters
|
|
84
94
|
def on_job(node)
|
85
95
|
jobs, state, *nodes = *node
|
86
96
|
jobs = clean_job(jobs)
|
87
|
-
|
97
|
+
runtime_control_variables << ['JOB', '']
|
88
98
|
condition = jobs.join(' or ')
|
89
99
|
line "if #{condition} then"
|
90
100
|
line '{'
|
@@ -16,8 +16,6 @@ module OrigenTesters
|
|
16
16
|
def initialize(options = {})
|
17
17
|
super
|
18
18
|
@initialized = true
|
19
|
-
@@pattern_masters ||= {}
|
20
|
-
@@pattern_compilers ||= {}
|
21
19
|
end
|
22
20
|
|
23
21
|
def add_tml(name, methods)
|
@@ -43,12 +41,14 @@ module OrigenTesters
|
|
43
41
|
@@flow_sheets = nil
|
44
42
|
@@pattern_masters = nil
|
45
43
|
@@pattern_compilers = nil
|
44
|
+
@@variables_files = nil
|
46
45
|
end
|
47
46
|
alias_method :reset_globals, :at_run_start
|
48
47
|
|
49
48
|
def resources_filename=(name)
|
50
49
|
self.pattern_master_filename = name
|
51
50
|
self.pattern_references_name = name
|
51
|
+
flow.var_filename = name
|
52
52
|
end
|
53
53
|
|
54
54
|
def pattern_master_filename=(name)
|
@@ -75,8 +75,7 @@ module OrigenTesters
|
|
75
75
|
# master file called 'global' will be used for all flows.
|
76
76
|
# To use a different one set the resources_filename at the start of the flow.
|
77
77
|
def pattern_master
|
78
|
-
|
79
|
-
@@pattern_masters[pattern_master_filename] ||= begin
|
78
|
+
pattern_masters[pattern_master_filename] ||= begin
|
80
79
|
m = platform::PatternMaster.new(manually_register: true)
|
81
80
|
name = "#{pattern_master_filename}.pmfl"
|
82
81
|
name = "#{Origen.config.program_prefix}_#{name}" if Origen.config.program_prefix
|
@@ -86,12 +85,16 @@ module OrigenTesters
|
|
86
85
|
end
|
87
86
|
end
|
88
87
|
|
88
|
+
# Returns a hash containing all pattern master generators
|
89
|
+
def pattern_masters
|
90
|
+
@@pattern_masters ||= {}
|
91
|
+
end
|
92
|
+
|
89
93
|
# Returns the pattern compiler file (.aiv) for the current flow, by default a common pattern
|
90
94
|
# compiler file called 'global' will be used for all flows.
|
91
95
|
# To use a different one set the resources_filename at the start of the flow.
|
92
96
|
def pattern_compiler
|
93
|
-
|
94
|
-
@@pattern_compilers[pattern_master_filename] ||= begin
|
97
|
+
pattern_compilers[pattern_master_filename] ||= begin
|
95
98
|
m = platform::PatternCompiler.new(manually_register: true)
|
96
99
|
name = "#{pattern_master_filename}.aiv"
|
97
100
|
name = "#{Origen.config.program_prefix}_#{name}" if Origen.config.program_prefix
|
@@ -101,6 +104,31 @@ module OrigenTesters
|
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
107
|
+
# Returns a hash containing all pattern compiler generators
|
108
|
+
def pattern_compilers
|
109
|
+
@@pattern_compilers ||= {}
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns the variables file for the current or given flow, by default a common variable
|
113
|
+
# file called 'global' will be used for all flows.
|
114
|
+
# To use a different one set the resources_filename at the start of the flow.
|
115
|
+
def variables_file(flw = nil)
|
116
|
+
name = (flw || flow).var_filename
|
117
|
+
variables_files[name] ||= begin
|
118
|
+
m = platform::VariablesFile.new(manually_register: true)
|
119
|
+
filename = "#{name}_vars.tf"
|
120
|
+
filename = "#{Origen.config.program_prefix}_#{filename}" if Origen.config.program_prefix
|
121
|
+
m.filename = filename
|
122
|
+
m.id = name
|
123
|
+
m
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns a hash containing all variables file generators
|
128
|
+
def variables_files
|
129
|
+
@@variables_files ||= {}
|
130
|
+
end
|
131
|
+
|
104
132
|
# @api private
|
105
133
|
def pattern_reference_recorded(name, options = {})
|
106
134
|
# Will be called everytime a pattern reference is made that the ATE should be aware of,
|
@@ -129,10 +157,13 @@ module OrigenTesters
|
|
129
157
|
flow_sheets.each do |_name, sheet|
|
130
158
|
g << sheet
|
131
159
|
end
|
132
|
-
|
160
|
+
pattern_masters.each do |name, sheet|
|
161
|
+
g << sheet
|
162
|
+
end
|
163
|
+
pattern_compilers.each do |name, sheet|
|
133
164
|
g << sheet
|
134
165
|
end
|
135
|
-
|
166
|
+
variables_files.each do |name, sheet|
|
136
167
|
g << sheet
|
137
168
|
end
|
138
169
|
g
|
@@ -85,6 +85,9 @@ module OrigenTesters
|
|
85
85
|
|
86
86
|
def initialize(name, attrs = {})
|
87
87
|
@name = name
|
88
|
+
if interface.flow.sig
|
89
|
+
@name = "#{name}_#{interface.flow.sig}"
|
90
|
+
end
|
88
91
|
# Set the defaults
|
89
92
|
DEFAULTS.each do |k, v|
|
90
93
|
send("#{k}=", v)
|
@@ -143,6 +146,10 @@ module OrigenTesters
|
|
143
146
|
(test_method && test_method.respond_to?(method)) || super
|
144
147
|
end
|
145
148
|
|
149
|
+
def interface
|
150
|
+
Origen.interface
|
151
|
+
end
|
152
|
+
|
146
153
|
private
|
147
154
|
|
148
155
|
def flags
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
module OrigenTesters
|
3
|
+
module SmartestBasedTester
|
4
|
+
class Base
|
5
|
+
class VariablesFile
|
6
|
+
include OrigenTesters::Generator
|
7
|
+
|
8
|
+
attr_reader :flow_control_variables, :runtime_control_variables
|
9
|
+
attr_accessor :filename, :id
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@flow_control_variables = []
|
13
|
+
@runtime_control_variables = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def subdirectory
|
17
|
+
'testflow/mfh.testflow.setup'
|
18
|
+
end
|
19
|
+
|
20
|
+
def clean_flow_control_variables
|
21
|
+
# These map to user flags and can only be integers
|
22
|
+
flow_control_variables.uniq.sort
|
23
|
+
end
|
24
|
+
|
25
|
+
def clean_runtime_control_variables
|
26
|
+
runtime_control_variables.uniq.sort do |x, y|
|
27
|
+
x = x[0] if x.is_a?(Array)
|
28
|
+
y = y[0] if y.is_a?(Array)
|
29
|
+
x <=> y
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -11,89 +11,90 @@ information
|
|
11
11
|
% end
|
12
12
|
% end
|
13
13
|
% else
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
%# Disabled for now, SMT master file doesn't like it
|
15
|
+
%#-- STOPDIFF
|
16
|
+
%#test_revision = "<%= Origen.app.version %>";
|
17
|
+
%#-- STARTDIFF
|
17
18
|
% end
|
18
19
|
|
19
20
|
end
|
20
|
-
|
21
|
-
declarations
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
21
|
+
%#--------------------------------------------------
|
22
|
+
%#declarations
|
23
|
+
%#
|
24
|
+
%#% if program
|
25
|
+
%#% program.declarations.each do |key, val|
|
26
|
+
%#<%= key %> = <%= val %>
|
27
|
+
%#% end
|
28
|
+
%#% else
|
29
|
+
%#% flow_control_variables.each do |var|
|
30
|
+
%#% if var.is_a?(Array)
|
31
|
+
%#@<%= var[0].to_s.upcase %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
|
32
|
+
%#% else
|
33
|
+
%#@<%= var.to_s.upcase %> = -1;
|
34
|
+
%#% end
|
35
|
+
%#% end
|
36
|
+
%#% runtime_control_variables.each do |var|
|
37
|
+
%#% if var.is_a?(Array)
|
38
|
+
%#@<%= var[0].to_s.upcase %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
|
39
|
+
%#% else
|
40
|
+
%#@<%= var.to_s.upcase %> = -1;
|
41
|
+
%#% end
|
42
|
+
%#% end
|
43
|
+
%#% end
|
44
|
+
%#end
|
44
45
|
--------------------------------------------------
|
45
46
|
implicit_declarations
|
46
47
|
|
47
48
|
end
|
48
49
|
-----------------------------------------------------------------
|
49
|
-
flags
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
datalog_formatter = 0;
|
57
|
-
datalog_sample_size = 1;
|
58
|
-
graphic_result_displa = 1;
|
59
|
-
state_display = 0;
|
60
|
-
print_wafermap = 0;
|
61
|
-
ink_wafer = 0;
|
62
|
-
max_reprobes = 1;
|
63
|
-
temp_monitor = 1;
|
64
|
-
calib_age_monitor = 1;
|
65
|
-
diag_monitor = 1;
|
66
|
-
current_monitor = 1;
|
67
|
-
log_events_enable = 1;
|
68
|
-
set_pass_level = 0;
|
69
|
-
set_fail_level = 0;
|
70
|
-
set_bypass_level = 0;
|
71
|
-
hold_on_fail = 0;
|
72
|
-
global_hold = 0;
|
73
|
-
debug_mode = 0;
|
74
|
-
debug_analog = 0;
|
75
|
-
parallel_mode = 1;
|
76
|
-
site_match_mode = 2;
|
77
|
-
global_overon = 0;
|
78
|
-
limits_enable = 0;
|
79
|
-
test_number_enable = 1;
|
80
|
-
test_number_inc = 1;
|
81
|
-
log_cycles_before = 0;
|
82
|
-
log_cycles_after = 0;
|
83
|
-
unburst_mode = 0;
|
84
|
-
sqst_mode = 0;
|
85
|
-
warn_as_fail = 1;
|
86
|
-
use_hw_dsp = 0;
|
87
|
-
dsp_file_enable = 0;
|
88
|
-
buffer_testflow_log = 0;
|
89
|
-
check_testmethod_api = 0;
|
90
|
-
stdf_generation = 1;
|
91
|
-
tm_crash_as_fatal = 1;
|
92
|
-
hidden_datalog_mode = 0;
|
93
|
-
multibin_mode = 0;
|
94
|
-
|
95
|
-
end
|
96
|
-
|
50
|
+
%#flags
|
51
|
+
%#
|
52
|
+
%#% if program
|
53
|
+
%#% program.flags.each do |key, val|
|
54
|
+
%#<%= key %> = <%= val %>
|
55
|
+
%#% end
|
56
|
+
%#% else
|
57
|
+
%#datalog_formatter = 0;
|
58
|
+
%#datalog_sample_size = 1;
|
59
|
+
%#graphic_result_displa = 1;
|
60
|
+
%#state_display = 0;
|
61
|
+
%#print_wafermap = 0;
|
62
|
+
%#ink_wafer = 0;
|
63
|
+
%#max_reprobes = 1;
|
64
|
+
%#temp_monitor = 1;
|
65
|
+
%#calib_age_monitor = 1;
|
66
|
+
%#diag_monitor = 1;
|
67
|
+
%#current_monitor = 1;
|
68
|
+
%#log_events_enable = 1;
|
69
|
+
%#set_pass_level = 0;
|
70
|
+
%#set_fail_level = 0;
|
71
|
+
%#set_bypass_level = 0;
|
72
|
+
%#hold_on_fail = 0;
|
73
|
+
%#global_hold = 0;
|
74
|
+
%#debug_mode = 0;
|
75
|
+
%#debug_analog = 0;
|
76
|
+
%#parallel_mode = 1;
|
77
|
+
%#site_match_mode = 2;
|
78
|
+
%#global_overon = 0;
|
79
|
+
%#limits_enable = 0;
|
80
|
+
%#test_number_enable = 1;
|
81
|
+
%#test_number_inc = 1;
|
82
|
+
%#log_cycles_before = 0;
|
83
|
+
%#log_cycles_after = 0;
|
84
|
+
%#unburst_mode = 0;
|
85
|
+
%#sqst_mode = 0;
|
86
|
+
%#warn_as_fail = 1;
|
87
|
+
%#use_hw_dsp = 0;
|
88
|
+
%#dsp_file_enable = 0;
|
89
|
+
%#buffer_testflow_log = 0;
|
90
|
+
%#check_testmethod_api = 0;
|
91
|
+
%#stdf_generation = 1;
|
92
|
+
%#tm_crash_as_fatal = 1;
|
93
|
+
%#hidden_datalog_mode = 0;
|
94
|
+
%#multibin_mode = 0;
|
95
|
+
%#% end
|
96
|
+
%#end
|
97
|
+
%#-----------------------------------------------------------------
|
97
98
|
testmethodparameters
|
98
99
|
% if program
|
99
100
|
% program.testmethodparameters.each do |id, parameters|
|
@@ -175,13 +176,15 @@ test_flow
|
|
175
176
|
% end
|
176
177
|
% else
|
177
178
|
{
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
179
|
+
%# {
|
180
|
+
%#% runtime_control_variables.each do |var|
|
181
|
+
%# @<%= var.to_s.upcase %> = -1;
|
182
|
+
%#% end
|
183
|
+
%# }, open,"Init Flow Control Vars", ""
|
182
184
|
% lines.each do |line|
|
183
|
-
<%= line %>
|
185
|
+
<%= line %>
|
184
186
|
% end
|
187
|
+
}, open,"<%= filename.sub(/\..*/, '').upcase %>", ""
|
185
188
|
% end
|
186
189
|
end
|
187
190
|
-------------------------------------------------
|
@@ -0,0 +1,48 @@
|
|
1
|
+
hp93000,testflow,0.1
|
2
|
+
language_revision = 1;
|
3
|
+
|
4
|
+
declarations
|
5
|
+
|
6
|
+
% clean_runtime_control_variables.each do |var|
|
7
|
+
% if var.is_a?(Array)
|
8
|
+
@<%= var[0].to_s.upcase %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
|
9
|
+
% else
|
10
|
+
@<%= var.to_s.upcase %> = 0;
|
11
|
+
% end
|
12
|
+
% end
|
13
|
+
|
14
|
+
end
|
15
|
+
-----------------------------------------------------------------
|
16
|
+
flags
|
17
|
+
|
18
|
+
% clean_flow_control_variables.each do |var|
|
19
|
+
% if var.is_a?(Array)
|
20
|
+
user <%= var[0].to_s.upcase %> = <%= var[1].is_a?(String) || var[1].is_a?(Symbol) ? "\"#{var[1]}\"" : var[1] %>;
|
21
|
+
% else
|
22
|
+
user <%= var.to_s.upcase %> = 0;
|
23
|
+
% end
|
24
|
+
% end
|
25
|
+
|
26
|
+
end
|
27
|
+
-----------------------------------------------------------------
|
28
|
+
testmethodparameters
|
29
|
+
end
|
30
|
+
-----------------------------------------------------------------
|
31
|
+
testmethodlimits
|
32
|
+
end
|
33
|
+
-----------------------------------------------------------------
|
34
|
+
test_flow
|
35
|
+
end
|
36
|
+
-----------------------------------------------------------------
|
37
|
+
binning
|
38
|
+
end
|
39
|
+
-----------------------------------------------------------------
|
40
|
+
oocrule
|
41
|
+
end
|
42
|
+
-----------------------------------------------------------------
|
43
|
+
context
|
44
|
+
end
|
45
|
+
-----------------------------------------------------------------
|
46
|
+
hardware_bin_descriptions
|
47
|
+
end
|
48
|
+
-----------------------------------------------------------------
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module OrigenTesters
|
2
|
+
module SmartestBasedTester
|
3
|
+
class V93K
|
4
|
+
require 'origen_testers/smartest_based_tester/base/variables_file'
|
5
|
+
class VariablesFile < Base::VariablesFile
|
6
|
+
TEMPLATE = "#{Origen.root!}/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
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.7.
|
4
|
+
version: 0.7.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: origen
|
@@ -310,6 +310,7 @@ files:
|
|
310
310
|
- lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb
|
311
311
|
- lib/origen_testers/smartest_based_tester/base/test_suite.rb
|
312
312
|
- lib/origen_testers/smartest_based_tester/base/test_suites.rb
|
313
|
+
- lib/origen_testers/smartest_based_tester/base/variables_file.rb
|
313
314
|
- lib/origen_testers/smartest_based_tester/v93k.rb
|
314
315
|
- lib/origen_testers/smartest_based_tester/v93k/builder.rb
|
315
316
|
- lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb
|
@@ -321,10 +322,12 @@ files:
|
|
321
322
|
- lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb
|
322
323
|
- lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb
|
323
324
|
- lib/origen_testers/smartest_based_tester/v93k/templates/template.tf.erb
|
325
|
+
- lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb
|
324
326
|
- lib/origen_testers/smartest_based_tester/v93k/test_method.rb
|
325
327
|
- lib/origen_testers/smartest_based_tester/v93k/test_methods.rb
|
326
328
|
- lib/origen_testers/smartest_based_tester/v93k/test_suite.rb
|
327
329
|
- lib/origen_testers/smartest_based_tester/v93k/test_suites.rb
|
330
|
+
- lib/origen_testers/smartest_based_tester/v93k/variables_file.rb
|
328
331
|
- lib/origen_testers/test/basic_interface.rb
|
329
332
|
- lib/origen_testers/test/block.rb
|
330
333
|
- lib/origen_testers/test/custom_test_interface.rb
|