test_ids 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37c789ce62a0733ee6b52dc37f744988ca6d06af
4
- data.tar.gz: 9061057b8a40d7e53486f660f5ca2dc129eb50c3
3
+ metadata.gz: a420dfdf8098943808de4f3f81202346fa8453c6
4
+ data.tar.gz: cd95837fd3c3086af0fb41fb3d9bcb71070725c3
5
5
  SHA512:
6
- metadata.gz: 421f88b79a4cc33f63bba116fbceda095828c2273bcc061450f3a119649e8295f4045ec4dac3086af9b7d4e2264e4d30f679fab0d4c46003585dd46d111e1de5
7
- data.tar.gz: 3db7247b32e50c47501202333fd38fc0a7b9e85fe323aa96ead79f697c279477a3bebd219b1a209ea76e257c6305ee1ccf1ca7f53b1f7e1527dc79dd53a43a79
6
+ metadata.gz: e402d3ac81c6d86bc5058ca6dd545ddf255c9bc1f68dd9d271f58099d6b1796a744df50067b91a2a69ebcf8e15758ebfa1eb332e476314da0e70563fb96f0c71
7
+ data.tar.gz: a41410e7b3ac45a93be182441fc0b4804ad1c4ef054dbbbb1af7cc66b5939310250695eb78fcb224dfad1923d1eed0bfd8badf1f6f80acf9a829bcfbd136eedf
data/config/commands.rb CHANGED
@@ -13,13 +13,10 @@ aliases ={
13
13
  # Now branch to the specific task code
14
14
  case @command
15
15
 
16
- # Here is an example of how to implement a command, the logic can go straight
17
- # in here or you can require an external file if preferred.
18
- when "my_command"
19
- puts "Doing something..."
20
- #require "commands/my_command" # Would load file lib/commands/my_command.rb
21
- # You must always exit upon successfully capturing a command to prevent
22
- # control flowing back to Origen
16
+ when "tags"
17
+ Dir.chdir Origen.root do
18
+ system("ripper-tags -R")
19
+ end
23
20
  exit 0
24
21
 
25
22
  # Example of how to make a command to run unit tests, this simply invokes RSpec on
@@ -63,6 +60,7 @@ else
63
60
  # origen -h, you can do this be assigning the required text to @application_commands
64
61
  # before handing control back to Origen. Un-comment the example below to get started.
65
62
  @application_commands = <<-EOT
63
+ tags Build a tags file for this app
66
64
  specs Run the specs (tests), -c will enable coverage
67
65
  examples Run the examples (tests), -c will enable coverage
68
66
  test Run both specs and examples, -c will enable coverage
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module TestIds
2
2
  MAJOR = 0
3
- MINOR = 6
4
- BUGFIX = 1
3
+ MINOR = 7
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -5,6 +5,8 @@ module TestIds
5
5
  # There is one allocator instance per configuration, and each has its own database
6
6
  # file.
7
7
  class Allocator
8
+ STORE_FORMAT_REVISION = 1
9
+
8
10
  attr_reader :config
9
11
 
10
12
  def initialize(configuration)
@@ -18,49 +20,109 @@ module TestIds
18
20
  @callbacks = []
19
21
  name = extract_test_name(instance, options)
20
22
  name = "#{name}_#{options[:index]}" if options[:index]
21
- store['tests'][name] ||= {}
22
- t = store['tests'][name]
23
+
24
+ # First work out the test ID to be used for each of the numbers, and how many numbers
25
+ # should be reserved
26
+ if (options[:bin].is_a?(Symbol) || options[:bin].is_a?(String)) && options[:bin] != :none
27
+ bin_id = options[:bin].to_s
28
+ else
29
+ bin_id = name
30
+ end
31
+ if (options[:softbin].is_a?(Symbol) || options[:softbin].is_a?(String)) && options[:softbin] != :none
32
+ softbin_id = options[:softbin].to_s
33
+ else
34
+ softbin_id = name
35
+ end
36
+ if (options[:number].is_a?(Symbol) || options[:number].is_a?(String)) && options[:number] != :none
37
+ number_id = options[:number].to_s
38
+ else
39
+ number_id = name
40
+ end
41
+
42
+ bin_size = options[:bin_size] || config.bins.size
43
+ softbin_size = options[:softbin_size] || config.softbins.size
44
+ number_size = options[:number_size] || config.numbers.size
45
+
46
+ bin = store['assigned']['bin'][bin_id] ||= {}
47
+ softbin = store['assigned']['softbin'][softbin_id] ||= {}
48
+ number = store['assigned']['number'][number_id] ||= {}
49
+
23
50
  # If the user has supplied any of these, that number should be used
24
51
  # and reserved so that it is not automatically generated later
25
52
  if options[:bin] && options[:bin].is_a?(Numeric)
26
- t['bin'] = options[:bin]
53
+ bin['number'] = options[:bin]
54
+ bin['size'] = bin_size
27
55
  store['manually_assigned']['bin'][options[:bin].to_s] = true
28
56
  # Regenerate the bin if the original allocation has since been applied
29
57
  # manually elsewhere
30
- elsif store['manually_assigned']['bin'][t['bin'].to_s]
31
- t['bin'] = nil
58
+ elsif store['manually_assigned']['bin'][bin['number'].to_s]
59
+ bin['number'] = nil
60
+ bin['size'] = nil
32
61
  # Also regenerate these as they could be a function of the bin
33
- t['softbin'] = nil if config.softbins.function?
34
- t['number'] = nil if config.numbers.function?
62
+ if config.softbins.function?
63
+ softbin['number'] = nil
64
+ softbin['size'] = nil
65
+ end
66
+ if config.numbers.function?
67
+ number['number'] = nil
68
+ number['size'] = nil
69
+ end
35
70
  end
36
71
  if options[:softbin] && options[:softbin].is_a?(Numeric)
37
- t['softbin'] = options[:softbin]
72
+ softbin['number'] = options[:softbin]
73
+ softbin['size'] = softbin_size
38
74
  store['manually_assigned']['softbin'][options[:softbin].to_s] = true
39
- elsif store['manually_assigned']['softbin'][t['softbin'].to_s]
40
- t['softbin'] = nil
75
+ elsif store['manually_assigned']['softbin'][softbin['number'].to_s]
76
+ softbin['number'] = nil
77
+ softbin['size'] = nil
41
78
  # Also regenerate the number as it could be a function of the softbin
42
- t['number'] = nil if config.numbers.function?
79
+ if config.numbers.function?
80
+ number['number'] = nil
81
+ number['size'] = nil
82
+ end
43
83
  end
44
84
  if options[:number] && options[:number].is_a?(Numeric)
45
- t['number'] = options[:number]
85
+ number['number'] = options[:number]
86
+ number['size'] = number_size
46
87
  store['manually_assigned']['number'][options[:number].to_s] = true
47
- elsif store['manually_assigned']['number'][t['number'].to_s]
48
- t['number'] = nil
88
+ elsif store['manually_assigned']['number'][number['number'].to_s]
89
+ number['number'] = nil
90
+ number['size'] = nil
49
91
  end
92
+
50
93
  # Otherwise generate the missing ones
51
- t['bin'] ||= allocate_bin
52
- t['softbin'] ||= allocate_softbin(t['bin'])
53
- t['number'] ||= allocate_number(t['bin'], t['softbin'])
94
+ bin['number'] ||= allocate_bin(size: bin_size)
95
+ bin['size'] ||= bin_size
96
+ softbin['number'] ||= allocate_softbin(bin: bin['number'], size: softbin_size)
97
+ softbin['size'] ||= softbin_size
98
+ number['number'] ||= allocate_number(bin: bin['number'], softbin: softbin['number'], size: number_size)
99
+ number['size'] ||= number_size
100
+
54
101
  # Record that there has been a reference to the final numbers
55
102
  time = Time.now.to_f
56
- store['references']['bin'][t['bin'].to_s] = time if t['bin'] && options[:bin] != :none
57
- store['references']['softbin'][t['softbin'].to_s] = time if t['softbin'] && options[:softbin] != :none
58
- store['references']['number'][t['number'].to_s] = time if t['number'] && options[:number] != :none
59
- # Update the supplied options hash that will be forwarded to the
60
- # program generator
61
- options[:bin] = t['bin'] unless options.delete(:bin) == :none
62
- options[:softbin] = t['softbin'] unless options.delete(:softbin) == :none
63
- options[:number] = t['number'] unless options.delete(:number) == :none
103
+ bin_size.times do |i|
104
+ store['references']['bin'][(bin['number'] + i).to_s] = time if bin['number'] && options[:bin] != :none
105
+ end
106
+ softbin_size.times do |i|
107
+ store['references']['softbin'][(softbin['number'] + i).to_s] = time if softbin['number'] && options[:softbin] != :none
108
+ end
109
+ number_size.times do |i|
110
+ store['references']['number'][(number['number'] + i).to_s] = time if number['number'] && options[:number] != :none
111
+ end
112
+
113
+ # Update the supplied options hash that will be forwarded to the program generator
114
+ unless options.delete(:bin) == :none
115
+ options[:bin] = bin['number']
116
+ options[:bin_size] = bin['size']
117
+ end
118
+ unless options.delete(:softbin) == :none
119
+ options[:softbin] = softbin['number']
120
+ options[:softbin_size] = softbin['size']
121
+ end
122
+ unless options.delete(:number) == :none
123
+ options[:number] = number['number']
124
+ options[:number_size] = number['size']
125
+ end
64
126
  options
65
127
  end
66
128
 
@@ -68,12 +130,30 @@ module TestIds
68
130
  @store ||= begin
69
131
  s = JSON.load(File.read(file)) if file && File.exist?(file)
70
132
  if s
133
+ if s['format_revision'] != STORE_FORMAT_REVISION
134
+ # Upgrade the original store format
135
+ t = { 'bin' => {}, 'softbin' => {}, 'number' => {} }
136
+ s['tests'].each do |name, numbers|
137
+ t['bin'][name] = { 'number' => numbers['bin'], 'size' => 1 }
138
+ t['softbin'][name] = { 'number' => numbers['softbin'], 'size' => 1 }
139
+ t['number'][name] = { 'number' => numbers['number'], 'size' => 1 }
140
+ end
141
+ s = {
142
+ 'format_revision' => STORE_FORMAT_REVISION,
143
+ 'assigned' => t,
144
+ 'manually_assigned' => s['manually_assigned'],
145
+ 'pointers' => s['pointers'],
146
+ 'references' => s['references']
147
+ }
148
+ end
71
149
  @last_bin = s['pointers']['bin']
72
150
  @last_softbin = s['pointers']['softbin']
73
151
  @last_number = s['pointers']['number']
74
152
  s
75
153
  else
76
- { 'tests' => {},
154
+ {
155
+ 'format_revision' => STORE_FORMAT_REVISION,
156
+ 'assigned' => { 'bin' => {}, 'softbin' => {}, 'number' => {} },
77
157
  'manually_assigned' => { 'bin' => {}, 'softbin' => {}, 'number' => {} },
78
158
  'pointers' => { 'bin' => nil, 'softbin' => nil, 'number' => nil },
79
159
  'references' => { 'bin' => {}, 'softbin' => {}, 'number' => {} }
@@ -108,15 +188,15 @@ module TestIds
108
188
 
109
189
  # Returns the next available bin in the pool, if they have all been given out
110
190
  # the one that hasn't been used for the longest time will be given out
111
- def allocate_bin
191
+ def allocate_bin(options)
112
192
  return nil if config.bins.empty?
113
193
  if store['pointers']['bin'] == 'done'
114
- reclaim_bin
194
+ reclaim_bin(options)
115
195
  else
116
- b = config.bins.include.next(@last_bin)
196
+ b = config.bins.include.next(after: @last_bin, size: options[:size])
117
197
  @last_bin = nil
118
198
  while b && (store['manually_assigned']['bin'][b.to_s] || config.bins.exclude.include?(b))
119
- b = config.bins.include.next
199
+ b = config.bins.include.next(size: options[:size])
120
200
  end
121
201
  # When no bin is returned it means we have used them all, all future generation
122
202
  # now switches to reclaim mode
@@ -124,17 +204,22 @@ module TestIds
124
204
  store['pointers']['bin'] = b
125
205
  else
126
206
  store['pointers']['bin'] = 'done'
127
- reclaim_bin
207
+ reclaim_bin(options)
128
208
  end
129
209
  end
130
210
  end
131
211
 
132
- def reclaim_bin
212
+ def reclaim_bin(options)
133
213
  store['references']['bin'] = store['references']['bin'].sort_by { |k, v| v }.to_h
134
- store['references']['bin'].first[0].to_i
214
+ if options[:size] == 1
215
+ store['references']['bin'].first[0].to_i
216
+ else
217
+ reclaim(store['references']['bin'], options)
218
+ end
135
219
  end
136
220
 
137
- def allocate_softbin(bin)
221
+ def allocate_softbin(options)
222
+ bin = options[:bin]
138
223
  return nil if config.softbins.empty?
139
224
  if config.softbins.algorithm
140
225
  algo = config.softbins.algorithm.to_s.downcase
@@ -180,12 +265,12 @@ module TestIds
180
265
  callback.call(bin)
181
266
  else
182
267
  if store['pointers']['softbin'] == 'done'
183
- reclaim_softbin
268
+ reclaim_softbin(options)
184
269
  else
185
- b = config.softbins.include.next(@last_softbin)
270
+ b = config.softbins.include.next(after: @last_softbin, size: options[:size])
186
271
  @last_softbin = nil
187
272
  while b && (store['manually_assigned']['softbin'][b.to_s] || config.softbins.exclude.include?(b))
188
- b = config.softbins.include.next
273
+ b = config.softbins.include.next(size: options[:size])
189
274
  end
190
275
  # When no softbin is returned it means we have used them all, all future generation
191
276
  # now switches to reclaim mode
@@ -193,18 +278,24 @@ module TestIds
193
278
  store['pointers']['softbin'] = b
194
279
  else
195
280
  store['pointers']['softbin'] = 'done'
196
- reclaim_softbin
281
+ reclaim_softbin(options)
197
282
  end
198
283
  end
199
284
  end
200
285
  end
201
286
 
202
- def reclaim_softbin
287
+ def reclaim_softbin(options)
203
288
  store['references']['softbin'] = store['references']['softbin'].sort_by { |k, v| v }.to_h
204
- store['references']['softbin'].first[0].to_i
289
+ if options[:size] == 1
290
+ store['references']['softbin'].first[0].to_i
291
+ else
292
+ reclaim(store['references']['softbin'], options)
293
+ end
205
294
  end
206
295
 
207
- def allocate_number(bin, softbin)
296
+ def allocate_number(options)
297
+ bin = options[:bin]
298
+ softbin = options[:softbin]
208
299
  return nil if config.numbers.empty?
209
300
  if config.numbers.algorithm
210
301
  algo = config.numbers.algorithm.to_s.downcase
@@ -258,12 +349,12 @@ module TestIds
258
349
  callback.call(bin, softbin)
259
350
  else
260
351
  if store['pointers']['number'] == 'done'
261
- reclaim_number
352
+ reclaim_number(options)
262
353
  else
263
- b = config.numbers.include.next(@last_number)
354
+ b = config.numbers.include.next(after: @last_number, size: options[:size])
264
355
  @last_number = nil
265
356
  while b && (store['manually_assigned']['number'][b.to_s] || config.numbers.exclude.include?(b))
266
- b = config.numbers.include.next
357
+ b = config.numbers.include.next(size: options[:size])
267
358
  end
268
359
  # When no number is returned it means we have used them all, all future generation
269
360
  # now switches to reclaim mode
@@ -271,15 +362,67 @@ module TestIds
271
362
  store['pointers']['number'] = b
272
363
  else
273
364
  store['pointers']['number'] = 'done'
274
- reclaim_number
365
+ reclaim_number(options)
275
366
  end
276
367
  end
277
368
  end
278
369
  end
279
370
 
280
- def reclaim_number
371
+ def reclaim_number(options)
281
372
  store['references']['number'] = store['references']['number'].sort_by { |k, v| v }.to_h
282
- store['references']['number'].first[0].to_i
373
+ if options[:size] == 1
374
+ store['references']['number'].first[0].to_i
375
+ else
376
+ reclaim(store['references']['number'], options)
377
+ end
378
+ end
379
+
380
+ # Returns the oldest number in the given reference hash, however also supports a :size option
381
+ # and in that case it will look for the oldest contiguous range of the given size
382
+ def reclaim(refs, options)
383
+ a = []
384
+ i = 0 # Pointer to references hash, which is already sorted with oldest first
385
+ s = 0 # Largest contiguous size in the array of considered numbers
386
+ p = 0 # Pointer to start of a suitable contiguous section in the array
387
+ while s < options[:size] && i < refs.size
388
+ a << refs.keys[i].to_i
389
+ a.sort!
390
+ s, p = largest_contiguous_section(a)
391
+ i += 1
392
+ end
393
+ a[p]
394
+ end
395
+
396
+ def largest_contiguous_section(array)
397
+ max_ptr = 0
398
+ max_size = 0
399
+ p = nil
400
+ s = nil
401
+ prev = nil
402
+ array.each_with_index do |v, i|
403
+ if prev
404
+ if v == prev + 1
405
+ s += 1
406
+ else
407
+ if s > max_size
408
+ max_size = s
409
+ max_ptr = p
410
+ end
411
+ p = i
412
+ s = 1
413
+ end
414
+ prev = v
415
+ else
416
+ p = i
417
+ s = 1
418
+ prev = v
419
+ end
420
+ end
421
+ if s > max_size
422
+ max_size = s
423
+ max_ptr = p
424
+ end
425
+ [max_size, max_ptr]
283
426
  end
284
427
 
285
428
  def extract_test_name(instance, options)
@@ -5,7 +5,7 @@ module TestIds
5
5
  end
6
6
 
7
7
  def <<(val)
8
- @store += Array(val)
8
+ @store << val
9
9
  @store = @store.sort do |a, b|
10
10
  a = a.min if a.is_a?(Range)
11
11
  b = b.min if b.is_a?(Range)
@@ -33,8 +33,9 @@ module TestIds
33
33
  # when called the next time.
34
34
  # A bin can optionally be supplied in which case the internal pointer will be reset and the
35
35
  # next bin that occurs after the given number will be returned.
36
- def next(after = nil)
37
- if after
36
+ def next(options = {})
37
+ if options[:after]
38
+ after = options[:after]
38
39
  # Need to work out the pointer here as it is probably out of sync with the
39
40
  # last value now
40
41
  @pointer = nil
@@ -79,7 +80,21 @@ module TestIds
79
80
  @next = v
80
81
  end
81
82
  end
82
- @next
83
+ if options[:size] && options[:size] > 1
84
+ # Check that all the numbers in the range to be reserved are included in the allocation,
85
+ # if not call again
86
+ included = true
87
+ options[:size].times { |i| included = false unless include?(@next + i) }
88
+ if included
89
+ n = @next
90
+ @next = @next + options[:size] - 1
91
+ n
92
+ else
93
+ self.next(after: @next, size: options[:size])
94
+ end
95
+ else
96
+ @next
97
+ end
83
98
  end
84
99
 
85
100
  def min
@@ -1,11 +1,12 @@
1
1
  module TestIds
2
2
  class Configuration
3
3
  class Item
4
- attr_accessor :include, :exclude, :algorithm
4
+ attr_accessor :include, :exclude, :algorithm, :size
5
5
 
6
6
  def initialize
7
7
  @include = BinArray.new
8
8
  @exclude = BinArray.new
9
+ @size = 1
9
10
  end
10
11
 
11
12
  def callback(&block)
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: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-16 00:00:00.000000000 Z
11
+ date: 2017-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -99,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  version: 1.8.11
100
100
  requirements: []
101
101
  rubyforge_project:
102
- rubygems_version: 2.6.7
102
+ rubygems_version: 2.5.2
103
103
  signing_key:
104
104
  specification_version: 4
105
105
  summary: Origen plugin to assign and track test program bins and test numbers