test_ids 1.1.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2715a10e5e999b8e7cb1d8240803232fadf178139e64a2f44186d69b65602a15
4
- data.tar.gz: 2b550ced04afc190362992970a7cfaeb76e7ba78d519894ebdeb04391cd3b721
3
+ metadata.gz: 3cc056bd639bd5288a0ed73842d5790de1beaf2d8ef53aefe004376fd2647ca2
4
+ data.tar.gz: 75ee0869b2c5d8a9e0e0ec75d9125bd8ad5286a1490af80e95ddcd986874b12e
5
5
  SHA512:
6
- metadata.gz: 4d62fc377c3bcbd5e840ed16c17e3749d7611f95e89eee17fe4bfa5ae7b572e6db8f12bf6016393f103e3dc2c59363205b5c90ad8ad999d43d87ba52017fd349
7
- data.tar.gz: dfe969df5389777ea3545f506b78046b0d5596d49fc37890b7eab748329337ee955050ed6756c0977d22420408b6329c1dcaab1f400e0d8ef744c386bd197f13
6
+ metadata.gz: ca98189aaf0d39ba9b4f7acac86354e5f6afa2c537dc3e6f70ebcce6413e607aeca2ed722f548c761432306729163c1b893ca4a10bbf2b711b217cd2418bfc58
7
+ data.tar.gz: 86b3b1023d650d963adf0cc4998dda002bec9bd925b4ac20e414f4215a765101ca7c8e5a8dfd84024eec4808e17fb61ca425a150218357955c622dc5d22d0bfc
@@ -83,7 +83,7 @@ class TestIdsApplication < Origen::Application
83
83
  puts "All tests passing, proceeding with release process!"
84
84
  end
85
85
  end
86
-
86
+
87
87
  # To enabled source-less pattern generation create a class (for example PatternDispatcher)
88
88
  # to generate the pattern. This should return false if the requested pattern has been
89
89
  # dispatched, otherwise Origen will proceed with looking up a pattern source as normal.
@@ -17,7 +17,7 @@ when "test_ids:clear", "test_ids:repair"
17
17
  else
18
18
  @plugin_commands << <<-EOT
19
19
  test_ids:rollback Rollback the TestIds store to the given commit ID
20
- test_ids:clear Clear the assignment database for bins, softbins, numbers or all
20
+ test_ids:clear Clear the assignment database for bins, softbins, numbers, ranges or all for the given configuration database ID
21
21
  test_ids:repair Repair the given database, see -h for more
22
22
  EOT
23
23
 
data/config/version.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  module TestIds
2
2
  MAJOR = 1
3
- MINOR = 1
4
- BUGFIX = 2
3
+ MINOR = 2
4
+ BUGFIX = 3
5
5
  DEV = nil
6
-
7
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
7
  end
@@ -28,11 +28,26 @@ module TestIds
28
28
  # If a numeric number is passed to the softbin, it uses that number.
29
29
  # The configuration for the TestId plugin needs to pass in the bin number and the options from the test flow
30
30
  # For this method to work as intended.
31
- def next_in_range(range, options)
32
- range_item(range, options)
31
+ # This will handle the following range inputs:
32
+ # - Range, Ex: 0..10
33
+ # - Array, Ex: [0..10, 20..30]
34
+ def next_in_range(range_definition, options)
35
+ if range_definition.is_a?(Range)
36
+ range = range_definition.to_a
37
+ elsif range_definition.is_a?(Array)
38
+ range = []
39
+ range_definition.each do |range_element|
40
+ range += range_element.is_a?(Integer) ? [range_element] : range_element.step(options[:size]).to_a
41
+ end
42
+ if range.uniq.size != range.size
43
+ Origen.log.error "Duplicate or overlapping range has been detected in configuration: \'#{TestIds.current_configuration.id}\'."
44
+ fail
45
+ end
46
+ end
47
+ range_item(range, range_definition, options)
33
48
  end
34
49
 
35
- def range_item(range, options)
50
+ def range_item(range, range_definition, options)
36
51
  # This is the actual fix, it should now not be dependent on the json file being read in, instead the store pointers
37
52
  # will be utilized to get the correct number assigned from the range.
38
53
  if store['pointers']['ranges'].nil?
@@ -43,33 +58,33 @@ module TestIds
43
58
  end
44
59
  orig_options = options.dup
45
60
  # Check the database to see if the passed in range has already been included in the database hash
46
- if rangehash.key?(:"#{range}")
61
+ if rangehash.key?(:"#{range_definition}")
47
62
  # Read out the database hash to see what the last_softbin given out was for that range.
48
63
  # This hash is updated whenever a new softbin is assigned, so it should have the updated values for each range.
49
- previous_assigned_value = rangehash[:"#{range}"].to_i
64
+ previous_assigned_value = rangehash[:"#{range_definition}"].to_i
50
65
  # Now calculate the new pointer.
51
- @pointer = previous_assigned_value - range.min
66
+ @pointer = range.index(previous_assigned_value) + 1
52
67
  # Check if the last_softbin given out is the same as the range[@pointer],
53
68
  # if so increment pointer by softbin size, default size is 1, config.softbins.size is configurable.
54
69
  # from example above, pointer was calculated as 1,range[1] is 10101 and is same as last_softbin, so pointer is incremented
55
70
  # and new value is assigned to the softbin.
56
- if previous_assigned_value == range.to_a[@pointer]
71
+ if previous_assigned_value == range[@pointer]
57
72
  @pointer += options[:size]
58
- assigned_value = range.to_a[@pointer]
73
+ assigned_value = range[@pointer]
59
74
  else
60
75
  # Because of the pointer calculations above, I don't think it will ever reach here, has not in my test cases so far!
61
- assigned_value = range.to_a[@pointer]
76
+ assigned_value = range[@pointer]
62
77
  end
63
78
  # Now update the database pointers to point to the lastest assigned softbin for a given range.
64
- rangehash.merge!(:"#{range}" => "#{range.to_a[@pointer]}")
79
+ rangehash.merge!(:"#{range_definition}" => "#{range[@pointer]}")
65
80
  else
66
81
  # This is the case for a brand new range that has not been passed before
67
82
  # We start from the first value as the assigned softbin and update the database to reflect.
68
83
  @pointer = 0
69
- rangehash.merge!(:"#{range}" => "#{range.to_a[@pointer]}")
70
- assigned_value = range.to_a[@pointer]
84
+ rangehash.merge!(:"#{range_definition}" => "#{range[@pointer]}")
85
+ assigned_value = range[@pointer]
71
86
  end
72
- unless !assigned_value.nil? && assigned_value.between?(range.min, range.max)
87
+ unless !assigned_value.nil? && range.include?(assigned_value)
73
88
  Origen.log.error 'Assigned value not in range'
74
89
  fail
75
90
  end
@@ -281,7 +296,7 @@ module TestIds
281
296
  end
282
297
  end
283
298
 
284
- # Clear the :bins, :softbins and/or :numbers by setting the options for each item to true
299
+ # Clear the :bins, :softbins and/or :numbers and/or :ranges by setting the options for each item
285
300
  def clear(options)
286
301
  if options[:softbin] || options[:softbins]
287
302
  store['assigned']['softbins'] = {}
@@ -301,6 +316,9 @@ module TestIds
301
316
  store['pointers']['numbers'] = nil
302
317
  store['references']['numbers'] = {}
303
318
  end
319
+ if options[:range] || options[:ranges]
320
+ store['pointers']['ranges'] = nil
321
+ end
304
322
  end
305
323
 
306
324
  # Saves the current allocator state to the repository
@@ -18,6 +18,7 @@ Examples: origen test_ids:clear --bins # Clear the bins in
18
18
  opts.on('--bins', 'Clear the bin database') { options[:bins] = true }
19
19
  opts.on('--softbins', 'Clear the softbin database') { options[:softbins] = true }
20
20
  opts.on('--numbers', 'Clear the test number database') { options[:numbers] = true }
21
+ opts.on('--ranges', 'Clear the ranges database') { options[:ranges] = true }
21
22
  # opts.on('-pl', '--plugin PLUGIN_NAME', String, 'Set current plugin') { |pl_n| options[:current_plugin] = pl_n }
22
23
  opts.on('-d', '--debugger', 'Enable the debugger') { options[:debugger] = true }
23
24
  app_options.each do |app_option|
@@ -38,6 +39,11 @@ begin
38
39
  # Get the commit before the lock to give the user later
39
40
  rollback_id = git.repo.object('HEAD^').sha[0, 11]
40
41
  a = TestIds.load_allocator(ARGV.first)
42
+ if a.nil?
43
+ Origen.log.error "No configuration file could be found for file ID: '#{ARGV.first}'!"
44
+ Origen.log.warn 'By default, the correct ID to pass in will need to match the filename in the form: store_<file id>.json'
45
+ fail
46
+ end
41
47
  a.clear(options)
42
48
  a.save
43
49
  ensure
data/lib/test_ids/git.rb CHANGED
@@ -50,26 +50,28 @@ module TestIds
50
50
  end
51
51
 
52
52
  def initialize(options)
53
- unless File.exist?("#{options[:local]}/.git")
54
- FileUtils.rm_rf(options[:local]) if File.exist?(options[:local])
55
- FileUtils.mkdir_p(options[:local])
56
- Dir.chdir options[:local] do
57
- `git clone #{options[:remote]} .`
58
- unless File.exist?('lock.json')
59
- # Should really try to use the Git driver for this
60
- exec 'touch lock.json'
61
- exec 'git add lock.json'
62
- exec 'git commit -m "Initial commit"'
63
- exec 'git push'
53
+ if !(TestIds.lsf_manual_init_shutdown) && Origen.running_locally?
54
+ unless File.exist?("#{options[:local]}/.git")
55
+ FileUtils.rm_rf(options[:local]) if File.exist?(options[:local])
56
+ FileUtils.mkdir_p(options[:local])
57
+ Dir.chdir options[:local] do
58
+ `git clone #{options[:remote]} .`
59
+ unless File.exist?('lock.json')
60
+ # Should really try to use the Git driver for this
61
+ exec 'touch lock.json'
62
+ exec 'git add lock.json'
63
+ exec 'git commit -m "Initial commit"'
64
+ exec 'git push'
65
+ end
64
66
  end
65
67
  end
68
+ @local = options[:local]
69
+ @repo = ::Git.open(options[:local])
70
+ # Get rid of any local edits coming in here, this is only called once at the start
71
+ # of the program generation run.
72
+ # No need to pull latest as that will be done when we obtain a lock.
73
+ @repo.reset_hard
66
74
  end
67
- @local = options[:local]
68
- @repo = ::Git.open(options[:local])
69
- # Get rid of any local edits coming in here, this is only called once at the start
70
- # of the program generation run.
71
- # No need to pull latest as that will be done when we obtain a lock.
72
- @repo.reset_hard
73
75
  end
74
76
 
75
77
  # Roll the repo back to the given commit ID
@@ -108,11 +110,13 @@ module TestIds
108
110
  end
109
111
 
110
112
  def publish
111
- Origen.profile 'Publishing the test IDs store' do
112
- release_lock
113
- repo.add # Checkin everything
114
- repo.commit('Publishing latest store')
115
- repo.push('origin', 'master', force: true)
113
+ if !(TestIds.lsf_manual_init_shutdown) && Origen.running_locally?
114
+ Origen.profile 'Publishing the test IDs store' do
115
+ release_lock
116
+ repo.add # Checkin everything
117
+ repo.commit('Publishing latest store')
118
+ repo.push('origin', 'master', force: true)
119
+ end
116
120
  end
117
121
  end
118
122
 
@@ -124,23 +128,25 @@ module TestIds
124
128
  end
125
129
 
126
130
  def get_lock
127
- return if @lock_open
128
- Origen.profile 'Obtaining test IDs lock' do
129
- until available_to_lock?
130
- puts
131
- puts "Waiting for lock, currently locked by #{lock_user} (the lock will expire in less than #{lock_minutes_remaining} #{'minute'.pluralize(lock_minutes_remaining)} if not released before that)"
132
- puts
133
- sleep 5
131
+ if !(TestIds.lsf_manual_init_shutdown) && Origen.running_locally?
132
+ return if @lock_open
133
+ Origen.profile 'Obtaining test IDs lock' do
134
+ until available_to_lock?(@repo)
135
+ puts
136
+ puts "Waiting for lock, currently locked by #{lock_user} (the lock will expire in less than #{lock_minutes_remaining} #{'minute'.pluralize(lock_minutes_remaining)} if not released before that)"
137
+ puts
138
+ sleep 5
139
+ end
140
+ data = {
141
+ 'user' => User.current.name,
142
+ 'expires' => (Time.now + minutes(5)).to_f
143
+ }
144
+ write('lock.json', JSON.pretty_generate(data))
145
+ repo.commit('Obtaining lock')
146
+ repo.push('origin')
134
147
  end
135
- data = {
136
- 'user' => User.current.name,
137
- 'expires' => (Time.now + minutes(5)).to_f
138
- }
139
- write('lock.json', JSON.pretty_generate(data))
140
- repo.commit('Obtaining lock')
141
- repo.push('origin')
148
+ @lock_open = true
142
149
  end
143
- @lock_open = true
144
150
  end
145
151
 
146
152
  def release_lock
@@ -151,11 +157,11 @@ module TestIds
151
157
  write('lock.json', JSON.pretty_generate(data))
152
158
  end
153
159
 
154
- def available_to_lock?
160
+ def available_to_lock?(repo_to_use)
155
161
  result = false
156
162
  Origen.profile 'Checking for lock' do
157
- repo.fetch
158
- repo.reset_hard('origin/master')
163
+ repo_to_use.fetch
164
+ repo_to_use.reset_hard('origin/master')
159
165
  if lock_content && lock_user && lock_user != User.current.name
160
166
  result = Time.now.to_f > lock_expires
161
167
  else
data/lib/test_ids.rb CHANGED
@@ -239,10 +239,78 @@ module TestIds
239
239
  @publish = val ? :save : :dont_save
240
240
  end
241
241
 
242
+ def lsf_manual_init_shutdown
243
+ if @lsf_manual_init_shutdown
244
+ true
245
+ end
246
+ false
247
+ end
248
+
242
249
  def next_in_range(range, options)
243
250
  current_configuration.allocator.next_in_range(range, options)
244
251
  end
245
252
 
253
+ def lsf_init(git_repo, lsf_publish)
254
+ @lsf_manual_init_shutdown = true
255
+ local_var_git_database_dir = "#{Origen.app.imports_directory}/test_ids/#{Pathname.new(git_repo).basename}"
256
+ FileUtils.mkdir_p(local_var_git_database_dir)
257
+ unless File.exist?("#{local_var_git_database_dir}/.git")
258
+ FileUtils.rm_rf(local_var_git_database_dir) if File.exist?(local_var_git_database_dir)
259
+ FileUtils.mkdir_p(local_var_git_database_dir)
260
+ Dir.chdir local_var_git_database_dir do
261
+ `git clone #{git_repo} .`
262
+ unless File.exist?('lock.json')
263
+ # Should really try to use the Git driver for this
264
+ exec 'touch lock.json'
265
+ exec 'git add lock.json'
266
+ exec 'git commit -m "Initial commit"'
267
+ exec 'git push'
268
+ end
269
+ end
270
+ end
271
+ @local = local_var_git_database_dir
272
+ @repo = ::Git.open(local_var_git_database_dir)
273
+ # Get rid of any local edits coming in here, this is only called once at the start
274
+ # of the program generation run.
275
+ # No need to pull latest as that will be done when we obtain a lock.
276
+ @repo.reset_hard
277
+ @git = Git.new(local: local_var_git_database_dir, remote: @repo)
278
+ if lsf_publish
279
+ return if @lock_open
280
+ Origen.profile 'Obtaining test IDs lock' do
281
+ until @git.available_to_lock?(@repo)
282
+ puts
283
+ puts "Waiting for lock, currently locked by #{@git.lock_user} (the lock will expire in less than #{@git.lock_minutes_remaining} #{'minute'.pluralize(@git.lock_minutes_remaining)} if not released before that)"
284
+ puts
285
+ sleep 5
286
+ end
287
+ data = {
288
+ 'user' => User.current.name,
289
+ 'expires' => (Time.now + @git.minutes(5)).to_f
290
+ }
291
+ @git.write('lock.json', JSON.pretty_generate(data))
292
+ repo.commit('Obtaining lock')
293
+ repo.push('origin')
294
+ end
295
+ @lock_open = true
296
+ end
297
+ end
298
+
299
+ def lsf_shutdown(lsf_publish)
300
+ if lsf_publish
301
+ Origen.profile 'Publishing the test IDs store' do
302
+ data = {
303
+ 'user' => nil,
304
+ 'expires' => nil
305
+ }
306
+ @git.write('lock.json', JSON.pretty_generate(data))
307
+ repo.add # Checkin everything
308
+ repo.commit('Publishing latest store')
309
+ repo.push('origin', 'master', force: true)
310
+ end
311
+ end
312
+ end
313
+
246
314
  ## When set to true, all numbers generated will be checked to see if they comply
247
315
  ## with the current configuration, and if not they will be re-assigned based on the
248
316
  ## current configuration
@@ -257,6 +325,24 @@ module TestIds
257
325
  # @reallocate_non_compliant = val
258
326
  # end
259
327
 
328
+ # Reset everything related to the TestIds module
329
+ # only needed for cases where running several targets
330
+ # back to back, e.g. for regression testing
331
+ def reset_everything(are_you_sure: false)
332
+ if are_you_sure
333
+ @repo = nil # accessor
334
+ @git = nil # accessor
335
+ @git_database_dir = nil
336
+ @git_initialized = nil
337
+ @configuration = nil
338
+ @configuration_id = nil
339
+ @bin_config = nil
340
+ @softbin_config = nil
341
+ @number_config = nil
342
+ @publish = nil
343
+ end
344
+ end
345
+
260
346
  private
261
347
 
262
348
  def on_origen_shutdown
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: 1.1.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-23 00:00:00.000000000 Z
11
+ date: 2022-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -16,14 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.7.40
19
+ version: 0.57.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.7.40
26
+ version: 0.57.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: dentaku
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-inflector
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.2.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.2.0
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: origen_testers
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -100,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
128
  - !ruby/object:Gem::Version
101
129
  version: 1.8.11
102
130
  requirements: []
103
- rubygems_version: 3.0.3
131
+ rubygems_version: 3.2.31
104
132
  signing_key:
105
133
  specification_version: 4
106
134
  summary: Origen plugin to assign and track test program bins and test numbers