test_ids 0.8.1 → 1.1.2
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 +5 -5
- data/config/commands.rb +2 -0
- data/config/version.rb +3 -3
- data/lib/test_ids.rb +93 -17
- data/lib/test_ids/allocator.rb +199 -281
- data/lib/test_ids/configuration.rb +32 -14
- data/lib/test_ids/origen_testers/flow.rb +9 -6
- data/lib/test_ids_dev/interface.rb +9 -3
- data/program/prb1.rb +12 -5
- metadata +3 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2715a10e5e999b8e7cb1d8240803232fadf178139e64a2f44186d69b65602a15
|
|
4
|
+
data.tar.gz: 2b550ced04afc190362992970a7cfaeb76e7ba78d519894ebdeb04391cd3b721
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d62fc377c3bcbd5e840ed16c17e3749d7611f95e89eee17fe4bfa5ae7b572e6db8f12bf6016393f103e3dc2c59363205b5c90ad8ad999d43d87ba52017fd349
|
|
7
|
+
data.tar.gz: dfe969df5389777ea3545f506b78046b0d5596d49fc37890b7eab748329337ee955050ed6756c0977d22420408b6329c1dcaab1f400e0d8ef744c386bd197f13
|
data/config/commands.rb
CHANGED
|
@@ -33,6 +33,8 @@ when "examples", "test"
|
|
|
33
33
|
# Program generator integration test
|
|
34
34
|
ARGV = %w(program/prb1.rb -t default -e default -r approved)
|
|
35
35
|
load "#{Origen.top}/lib/origen/commands/program.rb"
|
|
36
|
+
ARGV = %W(program/prb1.rb -t dut2 -o #{Origen.root}/output/dut2 -e default -r approved/dut2)
|
|
37
|
+
load "#{Origen.top}/lib/origen/commands/program.rb"
|
|
36
38
|
|
|
37
39
|
if Origen.app.stats.changed_files == 0 &&
|
|
38
40
|
Origen.app.stats.new_files == 0 &&
|
data/config/version.rb
CHANGED
data/lib/test_ids.rb
CHANGED
|
@@ -24,12 +24,58 @@ module TestIds
|
|
|
24
24
|
# returned will be the same as would be injected into flow.test.
|
|
25
25
|
def allocate(instance, options = {})
|
|
26
26
|
opts = options.dup
|
|
27
|
+
inject_flow_id(opts)
|
|
27
28
|
current_configuration.allocator.allocate(instance, opts)
|
|
28
29
|
{ bin: opts[:bin], bin_size: opts[:bin_size], softbin: opts[:softbin], softbin_size: opts[:softbin_size],
|
|
29
30
|
number: opts[:number], number_size: opts[:number_size]
|
|
30
31
|
}
|
|
31
32
|
end
|
|
32
33
|
|
|
34
|
+
# Similar to allocate, but allocates a test number only, i.e. no bin or softbin
|
|
35
|
+
def allocate_number(instance, options = {})
|
|
36
|
+
opts = options.dup
|
|
37
|
+
opts[:bin] = :none
|
|
38
|
+
opts[:softbin] = :none
|
|
39
|
+
inject_flow_id(opts)
|
|
40
|
+
current_configuration.allocator.allocate(instance, opts)
|
|
41
|
+
{
|
|
42
|
+
number: opts[:number], number_size: opts[:number_size]
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Similar to allocate, but allocates a softbin number only, i.e. no bin or test number
|
|
47
|
+
def allocate_softbin(instance, options = {})
|
|
48
|
+
opts = options.dup
|
|
49
|
+
opts[:bin] = :none
|
|
50
|
+
opts[:number] = :none
|
|
51
|
+
inject_flow_id(opts)
|
|
52
|
+
current_configuration.allocator.allocate(instance, opts)
|
|
53
|
+
{
|
|
54
|
+
softbin: opts[:softbin], softbin_size: opts[:softbin_size]
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
alias_method :allocate_soft_bin, :allocate_softbin
|
|
58
|
+
|
|
59
|
+
# Similar to allocate, but allocates a bin number only, i.e. no softbin or test number
|
|
60
|
+
def allocate_bin(instance, options = {})
|
|
61
|
+
opts = options.dup
|
|
62
|
+
opts[:softbin] = :none
|
|
63
|
+
opts[:number] = :none
|
|
64
|
+
inject_flow_id(opts)
|
|
65
|
+
current_configuration.allocator.allocate(instance, opts)
|
|
66
|
+
{
|
|
67
|
+
softbin: opts[:bin], softbin_size: opts[:bin_size]
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @api private
|
|
72
|
+
def inject_flow_id(options)
|
|
73
|
+
if Origen.interface_loaded?
|
|
74
|
+
flow = Origen.interface.flow
|
|
75
|
+
options[:test_ids_flow_id] = flow.try(:top_level).try(:id) || flow.id
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
33
79
|
# Load an existing allocator, which will be loaded with a configuration based on what has
|
|
34
80
|
# been serialized into the database if present, otherwise it will have an empty configuration.
|
|
35
81
|
# Returns nil if the given database can not be found.
|
|
@@ -47,9 +93,11 @@ module TestIds
|
|
|
47
93
|
configuration(@configuration_id)
|
|
48
94
|
end
|
|
49
95
|
|
|
50
|
-
def configuration(id)
|
|
96
|
+
def configuration(id, fail_on_missing = true)
|
|
51
97
|
return @configuration[id] if @configuration && @configuration[id]
|
|
52
|
-
|
|
98
|
+
if fail_on_missing
|
|
99
|
+
fail('You have to create the configuration first before you can access it')
|
|
100
|
+
end
|
|
53
101
|
end
|
|
54
102
|
alias_method :config, :configuration
|
|
55
103
|
|
|
@@ -73,26 +121,51 @@ module TestIds
|
|
|
73
121
|
initialize_git
|
|
74
122
|
end
|
|
75
123
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
124
|
+
# Switch the current configuration to the given ID
|
|
125
|
+
def config=(id)
|
|
126
|
+
unless @configuration[id]
|
|
127
|
+
fail "The TestIds configuration '#{id}' has not been defined yet!"
|
|
128
|
+
end
|
|
129
|
+
@configuration_id = id
|
|
130
|
+
end
|
|
81
131
|
|
|
82
|
-
#
|
|
132
|
+
# Return an Array of configuration IDs
|
|
133
|
+
def configs
|
|
134
|
+
@configuration.ids
|
|
135
|
+
end
|
|
83
136
|
|
|
84
|
-
|
|
137
|
+
def bin_config=(id)
|
|
138
|
+
@bin_config = id
|
|
139
|
+
end
|
|
85
140
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# new.allocator.instance_variable_set('@config', new)
|
|
90
|
-
# @configuration[@configuration_id] = new
|
|
141
|
+
def bin_config
|
|
142
|
+
@bin_config ? configuration(@bin_config, false) : current_configuration
|
|
143
|
+
end
|
|
91
144
|
|
|
92
|
-
|
|
145
|
+
def softbin_config=(id)
|
|
146
|
+
@softbin_config = id
|
|
147
|
+
end
|
|
93
148
|
|
|
94
|
-
|
|
95
|
-
|
|
149
|
+
def softbin_config
|
|
150
|
+
@softbin_config ? configuration(@softbin_config, false) : current_configuration
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def number_config=(id)
|
|
154
|
+
@number_config = id
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def number_config
|
|
158
|
+
@number_config ? configuration(@number_config, false) : current_configuration
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Temporarily switches the current configuration to the given ID for the
|
|
162
|
+
# duration of the given block, then switches it back to what it was
|
|
163
|
+
def with_config(id)
|
|
164
|
+
orig = @configuration_id
|
|
165
|
+
@configuration_id = id
|
|
166
|
+
yield
|
|
167
|
+
@configuration_id = orig
|
|
168
|
+
end
|
|
96
169
|
|
|
97
170
|
def configured?
|
|
98
171
|
!!@configuration_id
|
|
@@ -205,6 +278,9 @@ module TestIds
|
|
|
205
278
|
|
|
206
279
|
def clear_configuration_id
|
|
207
280
|
@configuration_id = nil
|
|
281
|
+
@bin_config = nil
|
|
282
|
+
@softbin_config = nil
|
|
283
|
+
@number_config = nil
|
|
208
284
|
end
|
|
209
285
|
|
|
210
286
|
def testing=(val)
|
data/lib/test_ids/allocator.rb
CHANGED
|
@@ -8,12 +8,20 @@ module TestIds
|
|
|
8
8
|
class Allocator
|
|
9
9
|
STORE_FORMAT_REVISION = 2
|
|
10
10
|
|
|
11
|
-
attr_reader :config
|
|
12
|
-
|
|
13
11
|
def initialize(configuration)
|
|
14
12
|
@config = configuration
|
|
15
13
|
end
|
|
16
14
|
|
|
15
|
+
def config(type = nil)
|
|
16
|
+
if type
|
|
17
|
+
type = type.to_s
|
|
18
|
+
type.chop! if type[-1] == 's'
|
|
19
|
+
TestIds.send("#{type}_config") || @config
|
|
20
|
+
else
|
|
21
|
+
@config
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
17
25
|
# Allocates a softbin number from the range specified in the test flow
|
|
18
26
|
# It also keeps a track of the last softbin assigned out from a particular range
|
|
19
27
|
# and uses that to increment the pointers accordingly.
|
|
@@ -25,9 +33,15 @@ module TestIds
|
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
def range_item(range, options)
|
|
36
|
+
# This is the actual fix, it should now not be dependent on the json file being read in, instead the store pointers
|
|
37
|
+
# will be utilized to get the correct number assigned from the range.
|
|
38
|
+
if store['pointers']['ranges'].nil?
|
|
39
|
+
rangehash = {}
|
|
40
|
+
else
|
|
41
|
+
rangehash = store['pointers']['ranges']
|
|
42
|
+
rangehash = Hash[rangehash.map { |k, v| [k.to_sym, v] }]
|
|
43
|
+
end
|
|
28
44
|
orig_options = options.dup
|
|
29
|
-
# Create an alias for the databse that stores the pointers per range
|
|
30
|
-
rangehash = store['pointers']['ranges'] ||= {}
|
|
31
45
|
# Check the database to see if the passed in range has already been included in the database hash
|
|
32
46
|
if rangehash.key?(:"#{range}")
|
|
33
47
|
# Read out the database hash to see what the last_softbin given out was for that range.
|
|
@@ -47,152 +61,114 @@ module TestIds
|
|
|
47
61
|
assigned_value = range.to_a[@pointer]
|
|
48
62
|
end
|
|
49
63
|
# Now update the database pointers to point to the lastest assigned softbin for a given range.
|
|
50
|
-
rangehash.merge!("#{range}"
|
|
64
|
+
rangehash.merge!(:"#{range}" => "#{range.to_a[@pointer]}")
|
|
51
65
|
else
|
|
52
66
|
# This is the case for a brand new range that has not been passed before
|
|
53
67
|
# We start from the first value as the assigned softbin and update the database to reflect.
|
|
54
68
|
@pointer = 0
|
|
55
|
-
rangehash.merge!("#{range}"
|
|
69
|
+
rangehash.merge!(:"#{range}" => "#{range.to_a[@pointer]}")
|
|
56
70
|
assigned_value = range.to_a[@pointer]
|
|
57
71
|
end
|
|
58
72
|
unless !assigned_value.nil? && assigned_value.between?(range.min, range.max)
|
|
59
73
|
Origen.log.error 'Assigned value not in range'
|
|
60
74
|
fail
|
|
61
75
|
end
|
|
76
|
+
# Since the assigned value for this test has now changed, update store to contain the newly assigned value
|
|
77
|
+
# so that when the json file is written, it contains the latest assigned value name.
|
|
78
|
+
store['pointers']['ranges'] = rangehash
|
|
62
79
|
assigned_value
|
|
63
80
|
end
|
|
64
81
|
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
# should be reserved
|
|
76
|
-
if (options[:bin].is_a?(Symbol) || options[:bin].is_a?(String)) && options[:bin] != :none
|
|
77
|
-
bin_id = options[:bin].to_s
|
|
82
|
+
# Returns an array containing :bin, :softbin, :number in the order that they should be calculated in order to fulfil
|
|
83
|
+
# the requirements of the current configuration and the given options.
|
|
84
|
+
# If an item is not required (e.g. if set to :none in the options), then it will not be present in the array.
|
|
85
|
+
def allocation_order(options)
|
|
86
|
+
items = []
|
|
87
|
+
items_required = 0
|
|
88
|
+
if allocation_required?(:bin, options) ||
|
|
89
|
+
(allocation_required?(:softbin, options) && config(:softbin).softbins.needs?(:bin)) ||
|
|
90
|
+
(allocation_required?(:number, options) && config(:number).numbers.needs?(:bin))
|
|
91
|
+
items_required += 1
|
|
78
92
|
else
|
|
79
|
-
|
|
93
|
+
bin_done = true
|
|
80
94
|
end
|
|
81
|
-
if (
|
|
82
|
-
|
|
95
|
+
if allocation_required?(:softbin, options) ||
|
|
96
|
+
(allocation_required?(:bin, options) && config(:bin).bins.needs?(:softbin)) ||
|
|
97
|
+
(allocation_required?(:number, options) && config(:number).numbers.needs?(:softbin))
|
|
98
|
+
items_required += 1
|
|
83
99
|
else
|
|
84
|
-
|
|
100
|
+
softbin_done = true
|
|
85
101
|
end
|
|
86
|
-
if (
|
|
87
|
-
|
|
102
|
+
if allocation_required?(:number, options) ||
|
|
103
|
+
(allocation_required?(:bin, options) && config(:bin).bins.needs?(:number)) ||
|
|
104
|
+
(allocation_required?(:softbin, options) && config(:softbin).softbins.needs?(:number))
|
|
105
|
+
items_required += 1
|
|
88
106
|
else
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
bin['number'] = options[:bin]
|
|
104
|
-
bin['size'] = bin_size
|
|
105
|
-
store['manually_assigned']['bins'][options[:bin].to_s] = true
|
|
106
|
-
# Regenerate the bin if the original allocation has since been applied
|
|
107
|
-
# manually elsewhere
|
|
108
|
-
elsif store['manually_assigned']['bins'][bin['number'].to_s]
|
|
109
|
-
bin['number'] = nil
|
|
110
|
-
bin['size'] = nil
|
|
111
|
-
# Also regenerate these as they could be a function of the bin
|
|
112
|
-
if config.softbins.function?
|
|
113
|
-
softbin['number'] = nil
|
|
114
|
-
softbin['size'] = nil
|
|
115
|
-
end
|
|
116
|
-
if config.numbers.function?
|
|
117
|
-
number['number'] = nil
|
|
118
|
-
number['size'] = nil
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
if options[:softbin] && options[:softbin].is_a?(Numeric)
|
|
122
|
-
softbin['number'] = options[:softbin]
|
|
123
|
-
softbin['size'] = softbin_size
|
|
124
|
-
store['manually_assigned']['softbins'][options[:softbin].to_s] = true
|
|
125
|
-
elsif store['manually_assigned']['softbins'][softbin['number'].to_s]
|
|
126
|
-
softbin['number'] = nil
|
|
127
|
-
softbin['size'] = nil
|
|
128
|
-
# Also regenerate the number as it could be a function of the softbin
|
|
129
|
-
if config.numbers.function?
|
|
130
|
-
number['number'] = nil
|
|
131
|
-
number['size'] = nil
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
if options[:number] && options[:number].is_a?(Numeric)
|
|
135
|
-
number['number'] = options[:number]
|
|
136
|
-
number['size'] = number_size
|
|
137
|
-
store['manually_assigned']['numbers'][options[:number].to_s] = true
|
|
138
|
-
elsif store['manually_assigned']['numbers'][number['number'].to_s]
|
|
139
|
-
number['number'] = nil
|
|
140
|
-
number['size'] = nil
|
|
141
|
-
# Also regenerate the softbin as it could be a function of the number
|
|
142
|
-
if config.softbins.function?
|
|
143
|
-
softbin['number'] = nil
|
|
144
|
-
softbin['size'] = nil
|
|
107
|
+
number_done = true
|
|
108
|
+
end
|
|
109
|
+
items_required.times do |i|
|
|
110
|
+
if !bin_done && (!config(:bin).bins.needs?(:softbin) || softbin_done) && (!config(:bin).bins.needs?(:number) || number_done)
|
|
111
|
+
items << :bin
|
|
112
|
+
bin_done = true
|
|
113
|
+
elsif !softbin_done && (!config(:softbin).softbins.needs?(:bin) || bin_done) && (!config(:softbin).softbins.needs?(:number) || number_done)
|
|
114
|
+
items << :softbin
|
|
115
|
+
softbin_done = true
|
|
116
|
+
elsif !number_done && (!config(:number).numbers.needs?(:bin) || bin_done) && (!config(:number).numbers.needs?(:softbin) || softbin_done)
|
|
117
|
+
items << :number
|
|
118
|
+
number_done = true
|
|
119
|
+
else
|
|
120
|
+
fail "Couldn't work out whether to generate next on iteration #{i} of #{items_required}, already picked: #{items}"
|
|
145
121
|
end
|
|
146
122
|
end
|
|
123
|
+
items
|
|
124
|
+
end
|
|
147
125
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (config.softbins.algorithm && config.softbins.algorithm.to_s =~ /n/) ||
|
|
155
|
-
(config.softbins.callback && !config.numbers.function?)
|
|
156
|
-
number['number'] ||= allocate_number(options.merge(bin: bin['number'], size: number_size))
|
|
157
|
-
number['size'] ||= number_size
|
|
158
|
-
softbin['number'] ||= allocate_softbin(options.merge(bin: bin['number'], number: number['number'], size: softbin_size))
|
|
159
|
-
softbin['size'] ||= softbin_size
|
|
160
|
-
else
|
|
161
|
-
softbin['number'] ||= allocate_softbin(options.merge(bin: bin['number'], size: softbin_size))
|
|
162
|
-
softbin['size'] ||= softbin_size
|
|
163
|
-
number['number'] ||= allocate_number(options.merge(bin: bin['number'], softbin: softbin['number'], size: number_size))
|
|
164
|
-
number['size'] ||= number_size
|
|
165
|
-
end
|
|
126
|
+
# Main method to inject generated bin and test numbers, the given
|
|
127
|
+
# options instance is modified accordingly
|
|
128
|
+
def allocate(instance, options)
|
|
129
|
+
orig_options = options.dup
|
|
130
|
+
clean(options)
|
|
131
|
+
name = extract_test_name(instance, options)
|
|
166
132
|
|
|
167
|
-
|
|
168
|
-
time = Time.now.to_f
|
|
169
|
-
bin_size.times do |i|
|
|
170
|
-
store['references']['bins'][(bin['number'] + i).to_s] = time if bin['number'] && options[:bin] != :none
|
|
171
|
-
end
|
|
172
|
-
softbin_size.times do |i|
|
|
173
|
-
store['references']['softbins'][(softbin['number'] + i).to_s] = time if softbin['number'] && options[:softbin] != :none
|
|
174
|
-
end
|
|
175
|
-
number_size.times do |i|
|
|
176
|
-
store['references']['numbers'][(number['number'] + i).to_s] = time if number['number'] && options[:number] != :none
|
|
177
|
-
end
|
|
133
|
+
nones = []
|
|
178
134
|
|
|
179
|
-
#
|
|
180
|
-
|
|
181
|
-
options[
|
|
182
|
-
|
|
135
|
+
# Record any :nones that are present for later
|
|
136
|
+
[:bin, :softbin, :number].each do |type|
|
|
137
|
+
nones << type if options[type] == :none
|
|
138
|
+
config(type).allocator.instance_variable_set('@needs_regenerated', {})
|
|
183
139
|
end
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
140
|
+
|
|
141
|
+
allocation_order(options).each do |type|
|
|
142
|
+
config(type).allocator.send(:_allocate, type, name, options)
|
|
187
143
|
end
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
144
|
+
|
|
145
|
+
# Turn any :nones into nils in the returned options
|
|
146
|
+
nones.each do |type|
|
|
147
|
+
options[type] = nil
|
|
148
|
+
options["#{type}_size"] = nil
|
|
191
149
|
end
|
|
192
150
|
|
|
193
151
|
options
|
|
194
152
|
end
|
|
195
153
|
|
|
154
|
+
# Merge the given other store into the current one, it is assumed that both are formatted
|
|
155
|
+
# from the same (latest) revision
|
|
156
|
+
def merge_store(other_store)
|
|
157
|
+
store['pointers'] = store['pointers'].merge(other_store['pointers'])
|
|
158
|
+
@last_bin = store['pointers']['bins']
|
|
159
|
+
@last_softbin = store['pointers']['softbins']
|
|
160
|
+
@last_number = store['pointers']['numbers']
|
|
161
|
+
store['assigned']['bins'] = store['assigned']['bins'].merge(other_store['assigned']['bins'])
|
|
162
|
+
store['assigned']['softbins'] = store['assigned']['softbins'].merge(other_store['assigned']['softbins'])
|
|
163
|
+
store['assigned']['numbers'] = store['assigned']['numbers'].merge(other_store['assigned']['numbers'])
|
|
164
|
+
store['manually_assigned']['bins'] = store['manually_assigned']['bins'].merge(other_store['manually_assigned']['bins'])
|
|
165
|
+
store['manually_assigned']['softbins'] = store['manually_assigned']['softbins'].merge(other_store['manually_assigned']['softbins'])
|
|
166
|
+
store['manually_assigned']['numbers'] = store['manually_assigned']['numbers'].merge(other_store['manually_assigned']['numbers'])
|
|
167
|
+
store['references']['bins'] = store['references']['bins'].merge(other_store['references']['bins'])
|
|
168
|
+
store['references']['softbins'] = store['references']['softbins'].merge(other_store['references']['softbins'])
|
|
169
|
+
store['references']['numbers'] = store['references']['numbers'].merge(other_store['references']['numbers'])
|
|
170
|
+
end
|
|
171
|
+
|
|
196
172
|
def store
|
|
197
173
|
@store ||= begin
|
|
198
174
|
if file && File.exist?(file)
|
|
@@ -256,7 +232,7 @@ module TestIds
|
|
|
256
232
|
{ 'bins' => 'bins', 'softbins' => 'softbins', 'numbers' => 'test_numbers' }.each do |type, name|
|
|
257
233
|
if !config.send(type).function? && store['pointers'][type] == 'done'
|
|
258
234
|
Origen.log.info "Checking for missing #{name}..."
|
|
259
|
-
recovered = add_missing_references(config.send
|
|
235
|
+
recovered = add_missing_references(config.send, store['references'][type])
|
|
260
236
|
if recovered == 0
|
|
261
237
|
Origen.log.info " All #{name} are already available."
|
|
262
238
|
else
|
|
@@ -385,6 +361,72 @@ module TestIds
|
|
|
385
361
|
|
|
386
362
|
private
|
|
387
363
|
|
|
364
|
+
def _allocate(type, name, options)
|
|
365
|
+
type_plural = "#{type}s"
|
|
366
|
+
conf = config.send(type_plural)
|
|
367
|
+
|
|
368
|
+
# First work out the test ID to be used for each of the numbers, and how many numbers
|
|
369
|
+
# should be reserved
|
|
370
|
+
if (options[type].is_a?(Symbol) || options[type].is_a?(String)) && options[type] != :none
|
|
371
|
+
id = options[type].to_s
|
|
372
|
+
else
|
|
373
|
+
id = name
|
|
374
|
+
end
|
|
375
|
+
id = "#{id}_#{options[:index]}" if options[:index]
|
|
376
|
+
id = "#{id}_#{options[:test_ids_flow_id]}" if config.unique_by_flow?
|
|
377
|
+
|
|
378
|
+
val = store['assigned'][type_plural][id] ||= {}
|
|
379
|
+
|
|
380
|
+
if options[type].is_a?(Integer)
|
|
381
|
+
unless val['number'] == options[type]
|
|
382
|
+
store['manually_assigned']["#{type}s"][options[type].to_s] = true
|
|
383
|
+
val['number'] = options[type]
|
|
384
|
+
end
|
|
385
|
+
else
|
|
386
|
+
# Will be set if an upstream dependent type has been marked for regeneration by the code below
|
|
387
|
+
if @needs_regenerated[type]
|
|
388
|
+
val['number'] = nil
|
|
389
|
+
val['size'] = nil
|
|
390
|
+
# Regenerate the number if the original allocation has since been applied manually elsewhere
|
|
391
|
+
elsif store['manually_assigned'][type_plural][val['number'].to_s]
|
|
392
|
+
val['number'] = nil
|
|
393
|
+
val['size'] = nil
|
|
394
|
+
# Also regenerate these as they could be a function of the number we just invalidated
|
|
395
|
+
([:bin, :softbin, :number] - [type]).each do |t|
|
|
396
|
+
if config.send("#{t}s").needs?(type)
|
|
397
|
+
@needs_regenerated[t] = true
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
if size = options["#{type}_size".to_sym]
|
|
404
|
+
val['size'] = size
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Generate the missing ones
|
|
408
|
+
val['size'] ||= conf.size
|
|
409
|
+
val['number'] ||= allocate_item(type, options.merge(size: val['size']))
|
|
410
|
+
|
|
411
|
+
# Record that there has been a reference to the final numbers
|
|
412
|
+
time = Time.now.to_f
|
|
413
|
+
val['size'].times do |i|
|
|
414
|
+
store['references'][type_plural][(val['number'] + i).to_s] = time if val['number'] && options[type] != :none
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
# Update the supplied options hash that will be forwarded to the program generator
|
|
418
|
+
options[type] = val['number']
|
|
419
|
+
options["#{type}_size".to_sym] = val['size']
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def allocation_required?(type, options)
|
|
423
|
+
if options[type] == :none
|
|
424
|
+
false
|
|
425
|
+
else
|
|
426
|
+
!config(type).send("#{type}s").empty?
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
388
430
|
def remove_invalid_references(config_item, references, manually_assigned)
|
|
389
431
|
removed = 0
|
|
390
432
|
references.each do |num, time|
|
|
@@ -424,161 +466,34 @@ module TestIds
|
|
|
424
466
|
recovered
|
|
425
467
|
end
|
|
426
468
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
return nil if config.bins.empty? && !config.bins.callback
|
|
434
|
-
if store['pointers']['bins'] == 'done'
|
|
435
|
-
reclaim_bin(options)
|
|
436
|
-
elsif callback = config.bins.callback
|
|
437
|
-
callback.call(options)
|
|
438
|
-
else
|
|
439
|
-
b = config.bins.include.next(after: @last_bin, size: options[:size])
|
|
440
|
-
@last_bin = nil
|
|
441
|
-
while b && (store['manually_assigned']['bins'][b.to_s] || config.bins.exclude.include?(b))
|
|
442
|
-
b = config.bins.include.next(size: options[:size])
|
|
443
|
-
end
|
|
444
|
-
# When no bin is returned it means we have used them all, all future generation
|
|
445
|
-
# now switches to reclaim mode
|
|
446
|
-
if b
|
|
447
|
-
store['pointers']['bins'] = b
|
|
448
|
-
else
|
|
449
|
-
store['pointers']['bins'] = 'done'
|
|
450
|
-
reclaim_bin(options)
|
|
451
|
-
end
|
|
452
|
-
end
|
|
453
|
-
end
|
|
454
|
-
|
|
455
|
-
def reclaim_bin(options)
|
|
456
|
-
store['references']['bins'] = store['references']['bins'].sort_by { |k, v| v }.to_h
|
|
457
|
-
if options[:size] == 1
|
|
458
|
-
store['references']['bins'].first[0].to_i
|
|
459
|
-
else
|
|
460
|
-
reclaim(store['references']['bins'], options)
|
|
461
|
-
end
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
def allocate_softbin(options)
|
|
465
|
-
bin = options[:bin]
|
|
466
|
-
num = options[:number]
|
|
467
|
-
return nil if config.softbins.empty?
|
|
468
|
-
if config.softbins.algorithm
|
|
469
|
-
algo = config.softbins.algorithm.to_s.downcase
|
|
470
|
-
if algo.to_s =~ /^[b\dxn]+$/
|
|
469
|
+
def allocate_item(type, options)
|
|
470
|
+
type_plural = "#{type}s"
|
|
471
|
+
conf = config.send(type_plural)
|
|
472
|
+
if conf.algorithm
|
|
473
|
+
algo = conf.algorithm.to_s.downcase
|
|
474
|
+
if algo.to_s =~ /^[bsn\dx]+$/
|
|
471
475
|
number = algo.to_s
|
|
472
|
-
bin
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
number = number.sub(/b+/, bin.rjust(max_bin_size, '0'))
|
|
479
|
-
end
|
|
480
|
-
if number =~ /(n+)/
|
|
481
|
-
num = num.to_s
|
|
482
|
-
max_num_size = Regexp.last_match(1).size
|
|
483
|
-
if num.size > max_num_size
|
|
484
|
-
fail "Test number (#{num}) overflows the softbin number algorithm (#{algo})"
|
|
485
|
-
end
|
|
486
|
-
number = number.sub(/n+/, num.rjust(max_num_size, '0'))
|
|
487
|
-
end
|
|
488
|
-
if number =~ /(x+)/
|
|
489
|
-
max_counter_size = Regexp.last_match(1).size
|
|
490
|
-
refs = store['references']['softbins']
|
|
491
|
-
i = 0
|
|
492
|
-
possible = []
|
|
493
|
-
proposal = number.sub(/x+/, i.to_s.rjust(max_counter_size, '0'))
|
|
494
|
-
possible << proposal
|
|
495
|
-
while refs[proposal] && i.to_s.size <= max_counter_size
|
|
496
|
-
i += 1
|
|
497
|
-
proposal = number.sub(/x+/, i.to_s.rjust(max_counter_size, '0'))
|
|
498
|
-
possible << proposal
|
|
499
|
-
end
|
|
500
|
-
# Overflowed, need to go search for the oldest duplicate now
|
|
501
|
-
if i.to_s.size > max_counter_size
|
|
502
|
-
i = 0
|
|
503
|
-
# Not the most efficient search algorithm, but this should be hit very rarely
|
|
504
|
-
# and even then only to generate the bin the first time around
|
|
505
|
-
p = refs.sort_by { |bin, last_used| last_used }.find do |bin, last_used|
|
|
506
|
-
possible.include?(bin)
|
|
476
|
+
([:bin, :softbin, :number] - [type]).each do |t|
|
|
477
|
+
if number =~ /(#{t.to_s[0]}+)/
|
|
478
|
+
max_size = Regexp.last_match(1).size
|
|
479
|
+
num = options[t].to_s
|
|
480
|
+
if num.size > max_size
|
|
481
|
+
fail "The allocated number, #{num}, overflows the #{t} field in the #{type} algorithm - #{algo}"
|
|
507
482
|
end
|
|
508
|
-
|
|
483
|
+
number = number.sub(/#{t.to_s[0]}+/, num.rjust(max_size, '0'))
|
|
509
484
|
end
|
|
510
|
-
number = proposal
|
|
511
|
-
end
|
|
512
|
-
else
|
|
513
|
-
fail "Unknown softbin algorithm: #{algo}"
|
|
514
|
-
end
|
|
515
|
-
number.to_i
|
|
516
|
-
elsif callback = config.softbins.callback
|
|
517
|
-
callback.call(bin, options)
|
|
518
|
-
else
|
|
519
|
-
if store['pointers']['softbins'] == 'done'
|
|
520
|
-
reclaim_softbin(options)
|
|
521
|
-
else
|
|
522
|
-
b = config.softbins.include.next(after: @last_softbin, size: options[:size])
|
|
523
|
-
@last_softbin = nil
|
|
524
|
-
while b && (store['manually_assigned']['softbins'][b.to_s] || config.softbins.exclude.include?(b))
|
|
525
|
-
b = config.softbins.include.next(size: options[:size])
|
|
526
|
-
end
|
|
527
|
-
# When no softbin is returned it means we have used them all, all future generation
|
|
528
|
-
# now switches to reclaim mode
|
|
529
|
-
if b
|
|
530
|
-
store['pointers']['softbins'] = b
|
|
531
|
-
else
|
|
532
|
-
store['pointers']['softbins'] = 'done'
|
|
533
|
-
reclaim_softbin(options)
|
|
534
485
|
end
|
|
535
|
-
end
|
|
536
|
-
end
|
|
537
|
-
end
|
|
538
|
-
|
|
539
|
-
def reclaim_softbin(options)
|
|
540
|
-
store['references']['softbins'] = store['references']['softbins'].sort_by { |k, v| v }.to_h
|
|
541
|
-
if options[:size] == 1
|
|
542
|
-
store['references']['softbins'].first[0].to_i
|
|
543
|
-
else
|
|
544
|
-
reclaim(store['references']['softbins'], options)
|
|
545
|
-
end
|
|
546
|
-
end
|
|
547
486
|
|
|
548
|
-
def allocate_number(options)
|
|
549
|
-
bin = options[:bin]
|
|
550
|
-
softbin = options[:softbin]
|
|
551
|
-
return nil if config.numbers.empty?
|
|
552
|
-
if config.numbers.algorithm
|
|
553
|
-
algo = config.numbers.algorithm.to_s.downcase
|
|
554
|
-
if algo.to_s =~ /^[bs\dx]+$/
|
|
555
|
-
number = algo.to_s
|
|
556
|
-
bin = bin.to_s
|
|
557
|
-
if number =~ /(b+)/
|
|
558
|
-
max_bin_size = Regexp.last_match(1).size
|
|
559
|
-
if bin.size > max_bin_size
|
|
560
|
-
fail "Bin number (#{bin}) overflows the test number algorithm (#{algo})"
|
|
561
|
-
end
|
|
562
|
-
number = number.sub(/b+/, bin.rjust(max_bin_size, '0'))
|
|
563
|
-
end
|
|
564
|
-
softbin = softbin.to_s
|
|
565
|
-
if number =~ /(s+)/
|
|
566
|
-
max_softbin_size = Regexp.last_match(1).size
|
|
567
|
-
if softbin.size > max_softbin_size
|
|
568
|
-
fail "Softbin number (#{softbin}) overflows the test number algorithm (#{algo})"
|
|
569
|
-
end
|
|
570
|
-
number = number.sub(/s+/, softbin.rjust(max_softbin_size, '0'))
|
|
571
|
-
end
|
|
572
487
|
if number =~ /(x+)/
|
|
573
488
|
max_counter_size = Regexp.last_match(1).size
|
|
574
|
-
refs = store['references'][
|
|
489
|
+
refs = store['references'][type_plural]
|
|
575
490
|
i = 0
|
|
576
491
|
possible = []
|
|
577
|
-
proposal = number.sub(/x+/, i.to_s.rjust(max_counter_size, '0'))
|
|
492
|
+
proposal = number.sub(/x+/, i.to_s.rjust(max_counter_size, '0')).to_i.to_s
|
|
578
493
|
possible << proposal
|
|
579
494
|
while refs[proposal] && i.to_s.size <= max_counter_size
|
|
580
495
|
i += 1
|
|
581
|
-
proposal = number.sub(/x+/, i.to_s.rjust(max_counter_size, '0'))
|
|
496
|
+
proposal = number.sub(/x+/, i.to_s.rjust(max_counter_size, '0')).to_i.to_s
|
|
582
497
|
possible << proposal
|
|
583
498
|
end
|
|
584
499
|
# Overflowed, need to go search for the oldest duplicate now
|
|
@@ -593,39 +508,42 @@ module TestIds
|
|
|
593
508
|
end
|
|
594
509
|
number = proposal
|
|
595
510
|
end
|
|
596
|
-
number.to_i
|
|
597
511
|
else
|
|
598
|
-
fail "
|
|
512
|
+
fail "Illegal algorithm: #{algo}"
|
|
599
513
|
end
|
|
600
|
-
|
|
601
|
-
|
|
514
|
+
number.to_i
|
|
515
|
+
elsif callback = conf.callback
|
|
516
|
+
callback.call(options)
|
|
602
517
|
else
|
|
603
|
-
if store['pointers'][
|
|
604
|
-
|
|
518
|
+
if store['pointers'][type_plural] == 'done'
|
|
519
|
+
reclaim_item(type, options)
|
|
605
520
|
else
|
|
606
|
-
b =
|
|
607
|
-
@
|
|
608
|
-
while b && (store['manually_assigned'][
|
|
609
|
-
b =
|
|
521
|
+
b = conf.include.next(after: instance_variable_get("@last_#{type}"), size: options[:size])
|
|
522
|
+
instance_variable_set("@last_#{type}", nil)
|
|
523
|
+
while b && (store['manually_assigned'][type_plural][b.to_s] || conf.exclude.include?(b))
|
|
524
|
+
b = conf.include.next(size: options[:size])
|
|
610
525
|
end
|
|
611
526
|
# When no number is returned it means we have used them all, all future generation
|
|
612
527
|
# now switches to reclaim mode
|
|
613
528
|
if b
|
|
614
|
-
store['pointers'][
|
|
529
|
+
store['pointers'][type_plural] = b + (options[:size] || 1) - 1
|
|
530
|
+
b
|
|
615
531
|
else
|
|
616
|
-
store['pointers'][
|
|
617
|
-
|
|
532
|
+
store['pointers'][type_plural] = 'done'
|
|
533
|
+
reclaim_item(type, options)
|
|
618
534
|
end
|
|
619
535
|
end
|
|
620
536
|
end
|
|
621
537
|
end
|
|
622
538
|
|
|
623
|
-
def
|
|
624
|
-
|
|
539
|
+
def reclaim_item(type, options)
|
|
540
|
+
type_plural = "#{type}s"
|
|
541
|
+
store['references'][type_plural] = store['references'][type_plural].sort_by { |k, v| v }.to_h
|
|
625
542
|
if options[:size] == 1
|
|
626
|
-
store['references'][
|
|
543
|
+
v = store['references'][type_plural].first
|
|
544
|
+
v[0].to_i if v
|
|
627
545
|
else
|
|
628
|
-
reclaim(store['references'][
|
|
546
|
+
reclaim(store['references'][type_plural], options)
|
|
629
547
|
end
|
|
630
548
|
end
|
|
631
549
|
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
module TestIds
|
|
2
2
|
class Configuration
|
|
3
3
|
class Item
|
|
4
|
-
attr_accessor :include, :exclude, :algorithm, :size
|
|
4
|
+
attr_accessor :include, :exclude, :algorithm, :size, :needs
|
|
5
5
|
|
|
6
6
|
def initialize
|
|
7
7
|
@include = BinArray.new
|
|
8
8
|
@exclude = BinArray.new
|
|
9
|
+
@needs = []
|
|
9
10
|
@size = 1
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def callback(&block)
|
|
13
|
+
def callback(options = {}, &block)
|
|
13
14
|
if block_given?
|
|
15
|
+
@needs += Array(options[:needs])
|
|
14
16
|
@callback = block
|
|
15
17
|
else
|
|
16
18
|
@callback
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
def needs?(type)
|
|
23
|
+
!!(!empty? && function? && (needs.include?(type) ||
|
|
24
|
+
(algorithm && (algorithm.to_s =~ /#{type.to_s[0]}/i))))
|
|
25
|
+
end
|
|
26
|
+
|
|
20
27
|
def empty?
|
|
21
28
|
include.empty? && exclude.empty? && !algorithm && !callback
|
|
22
29
|
end
|
|
@@ -36,6 +43,7 @@ module TestIds
|
|
|
36
43
|
def freeze
|
|
37
44
|
@include.freeze
|
|
38
45
|
@exclude.freeze
|
|
46
|
+
@needs.freeze
|
|
39
47
|
super
|
|
40
48
|
end
|
|
41
49
|
|
|
@@ -88,18 +96,23 @@ module TestIds
|
|
|
88
96
|
@id
|
|
89
97
|
end
|
|
90
98
|
|
|
91
|
-
def bins(&block)
|
|
99
|
+
def bins(options = {}, &block)
|
|
92
100
|
@bins ||= Item.new
|
|
93
101
|
if block_given?
|
|
94
|
-
@bins.callback(&block)
|
|
102
|
+
@bins.callback(options, &block)
|
|
95
103
|
end
|
|
96
104
|
@bins
|
|
97
105
|
end
|
|
98
106
|
|
|
99
|
-
|
|
107
|
+
# An alias for config.bins.algorithm=
|
|
108
|
+
def bins=(val)
|
|
109
|
+
bins.algorithm = val
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def softbins(options = {}, &block)
|
|
100
113
|
@softbins ||= Item.new
|
|
101
114
|
if block_given?
|
|
102
|
-
@softbins.callback(&block)
|
|
115
|
+
@softbins.callback(options, &block)
|
|
103
116
|
end
|
|
104
117
|
@softbins
|
|
105
118
|
end
|
|
@@ -109,10 +122,10 @@ module TestIds
|
|
|
109
122
|
softbins.algorithm = val
|
|
110
123
|
end
|
|
111
124
|
|
|
112
|
-
def numbers(&block)
|
|
125
|
+
def numbers(options = {}, &block)
|
|
113
126
|
@numbers ||= Item.new
|
|
114
127
|
if block_given?
|
|
115
|
-
@numbers.callback(&block)
|
|
128
|
+
@numbers.callback(options, &block)
|
|
116
129
|
end
|
|
117
130
|
@numbers
|
|
118
131
|
end
|
|
@@ -123,18 +136,23 @@ module TestIds
|
|
|
123
136
|
end
|
|
124
137
|
|
|
125
138
|
def send_to_ate=(val)
|
|
126
|
-
@send_to_ate = val
|
|
139
|
+
@send_to_ate = !!val
|
|
127
140
|
end
|
|
128
141
|
|
|
129
|
-
def send_to_ate
|
|
130
|
-
@send_to_ate
|
|
142
|
+
def send_to_ate?
|
|
143
|
+
defined?(@send_to_ate) ? @send_to_ate : true
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def unique_by_flow=(val)
|
|
147
|
+
@unique_by_flow = !!val
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def unique_by_flow?
|
|
151
|
+
@unique_by_flow || false
|
|
131
152
|
end
|
|
132
153
|
|
|
133
154
|
def validate!
|
|
134
155
|
unless validated?
|
|
135
|
-
if bins.algorithm
|
|
136
|
-
fail 'The TestIds bins configuration cannot be set to an algorithm, only a range set by bins.include and bins.exclude is permitted'
|
|
137
|
-
end
|
|
138
156
|
@validated = true
|
|
139
157
|
freeze
|
|
140
158
|
end
|
|
@@ -7,13 +7,16 @@ module OrigenTesters
|
|
|
7
7
|
# test numbers
|
|
8
8
|
alias_method :_orig_test, :test
|
|
9
9
|
def test(instance, options = {})
|
|
10
|
-
if TestIds.configured? && options[:test_ids] != :notrack
|
|
11
|
-
TestIds.current_configuration.allocator.allocate(instance, options)
|
|
12
|
-
end
|
|
13
10
|
if TestIds.configured?
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
unless options[:test_ids] == :notrack
|
|
12
|
+
options[:test_ids_flow_id] = try(:top_level).try(:id) || id
|
|
13
|
+
|
|
14
|
+
TestIds.current_configuration.allocator.allocate(instance, options)
|
|
15
|
+
|
|
16
|
+
unless TestIds.current_configuration.send_to_ate?
|
|
17
|
+
BIN_OPTS.each do |opt|
|
|
18
|
+
options.delete(opt)
|
|
19
|
+
end
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
22
|
end
|
|
@@ -5,17 +5,23 @@ module TestIdsDev
|
|
|
5
5
|
def initialize(options = {})
|
|
6
6
|
case dut.test_ids
|
|
7
7
|
when 1
|
|
8
|
-
TestIds.configure do |config|
|
|
8
|
+
TestIds.configure id: :cfg1 do |config|
|
|
9
9
|
# Example of testing remote repo
|
|
10
10
|
# config.repo = 'ssh://git@sw-stash.freescale.net/~r49409/test_ids_repo.git'
|
|
11
11
|
config.bins.include << 3
|
|
12
12
|
config.bins.include << (10..20)
|
|
13
13
|
config.bins.exclude << 15
|
|
14
14
|
config.softbins = :bbbxx
|
|
15
|
-
config.numbers do |
|
|
16
|
-
softbin * 100
|
|
15
|
+
config.numbers needs: :softbin do |options|
|
|
16
|
+
options[:softbin] * 100
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
when 2
|
|
21
|
+
TestIds.configure id: :cfg2 do |config|
|
|
22
|
+
config.bins.include << (5..16)
|
|
23
|
+
config.softbins = :bbxxx
|
|
24
|
+
end
|
|
19
25
|
end
|
|
20
26
|
end
|
|
21
27
|
|
data/program/prb1.rb
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
Flow.create do
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
if dut.test_ids == 2
|
|
3
|
+
func :t1, bin: 11
|
|
4
|
+
func :t2, bin: 11
|
|
5
|
+
func :t3, bin: 11
|
|
6
|
+
func :t4, bin: 11
|
|
7
|
+
func :t5, bin: 11
|
|
8
|
+
else
|
|
9
|
+
func :t1
|
|
10
|
+
func :t2
|
|
11
|
+
func :t3
|
|
12
|
+
func :t3, bin: :none, sbin: :none
|
|
13
|
+
end
|
|
7
14
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: test_ids
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen McGinty
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-07-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: origen
|
|
@@ -100,8 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
101
|
version: 1.8.11
|
|
102
102
|
requirements: []
|
|
103
|
-
|
|
104
|
-
rubygems_version: 2.6.7
|
|
103
|
+
rubygems_version: 3.0.3
|
|
105
104
|
signing_key:
|
|
106
105
|
specification_version: 4
|
|
107
106
|
summary: Origen plugin to assign and track test program bins and test numbers
|