test_ids 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37097520304a42cec66a48fdac2b192dda5451b0
4
- data.tar.gz: 6df4dd37ea78ec47a562f03a72f0503f37d304b0
3
+ metadata.gz: 32e0f28dcb31510be128dc89738ae51f437217bc
4
+ data.tar.gz: 3cbdd628afd3537d092e2ef60518a45342367e63
5
5
  SHA512:
6
- metadata.gz: 6609ad85bed7091b9b647a3ac24551b245a253b965d6ca2f99f99342da53f871af220a721d940269e2886d4111058938b4b3ee10a166180efcf5af00c7559214
7
- data.tar.gz: e3ab6e8d0ae659f2c6845032b8f021dd414a4c671778dfb61933c90dbf1f12573a09795368270827073c76c7e49536e21f9fe811ab4b947ca2e56b8f23f04d04
6
+ metadata.gz: 86e9efb2f2b12789ace7a19180235128c926faff668483ce1c359aa1d6133aa85df2a0b018f0355f268c49fd3bb8001bdb5410ceb5ef1cd4354fbff997be23ac
7
+ data.tar.gz: b5edb4c6e60077a18ef9e1d5d4b26f2970c4c0ab236e2fb269f4bcfcaec36a1c7838124ba94d9b8eb4a9110890b19b590d3cad8d120ae3927711ce647437140a
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module TestIds
2
2
  MAJOR = 0
3
- MINOR = 2
4
- BUGFIX = 1
3
+ MINOR = 3
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -1,20 +1,19 @@
1
1
  module TestIds
2
+ # The allocator is responsible for assigning new numbers and keeping a record of
3
+ # existing assignments.
4
+ #
5
+ # There is one allocator instance per configuration, and each has its own database
6
+ # file.
2
7
  class Allocator
3
- include Origen::Callbacks
4
8
  attr_reader :config
5
9
 
6
- def initialize
7
- @@allocators ||= 0
8
- @@allocators += 1
9
- if @@allocators > 1 && !TestIds.send(:testing?)
10
- fail 'TestIds::Allocators is a singleton, there can be only one'
11
- end
10
+ def initialize(configuration)
11
+ @config = configuration
12
12
  end
13
13
 
14
14
  # Main method to inject generated bin and test numbers, the given
15
15
  # options instance is modified accordingly
16
16
  def allocate(instance, options)
17
- @changes_made = true
18
17
  clean(options)
19
18
  @callbacks = []
20
19
  name = extract_test_name(instance, options)
@@ -65,10 +64,6 @@ module TestIds
65
64
  options
66
65
  end
67
66
 
68
- def config
69
- TestIds.config
70
- end
71
-
72
67
  def store
73
68
  @store ||= begin
74
69
  s = JSON.load(File.read(file)) if file && File.exist?(file)
@@ -96,40 +91,14 @@ module TestIds
96
91
  end
97
92
  end
98
93
 
99
- def on_origen_shutdown
100
- unless TestIds.send(:testing?)
101
- if config.repo && @changes_made && config.on_completion != :discard
102
- save
103
- git.publish if publish?
104
- end
105
- end
106
- end
107
-
108
- # Returns a path to the file that will be used to store the allocated bins/numbers.
109
- # If config.repo has not been set it returns nil.
94
+ # Returns a path to the file that will be used to store the allocated bins/numbers,
95
+ # returns nil if remote storage not enabled
110
96
  def file
111
- if config.repo
112
- @file ||= begin
113
- if git?
114
- dir = "#{Origen.app.imports_directory}/test_ids/#{Pathname.new(config.repo).basename}"
115
- FileUtils.mkdir_p(dir)
116
- "#{dir}/store.json"
117
- else
118
- config.repo
119
- end
120
- end
121
- end
97
+ TestIds.database_file(id)
122
98
  end
123
99
 
124
- def git
125
- @git ||= Git.new(local: Pathname.new(file).dirname, remote: config.repo, no_pull: publish?)
126
- end
127
-
128
- def prepare
129
- if git?
130
- git # Pulls the latest repo
131
- git.get_lock if publish?
132
- end
100
+ def id
101
+ config.id
133
102
  end
134
103
 
135
104
  private
@@ -31,18 +31,15 @@ module TestIds
31
31
  end
32
32
  end
33
33
 
34
- attr_accessor :repo
35
- attr_reader :on_completion
34
+ attr_reader :allocator
36
35
 
37
- def on_completion
38
- @on_completion || :publish
36
+ def initialize(id)
37
+ @id = id
38
+ @allocator = Allocator.new(self)
39
39
  end
40
40
 
41
- def on_completion=(val)
42
- unless %w(publish save discard).include?(val.to_s)
43
- fail 'on_completion must be set to one of: :publish, :save, :discard'
44
- end
45
- @on_completion = val.to_sym
41
+ def id
42
+ @id
46
43
  end
47
44
 
48
45
  def bins
data/lib/test_ids/git.rb CHANGED
@@ -18,10 +18,10 @@ module TestIds
18
18
  FileUtils.mkdir_p(options[:local])
19
19
  Dir.chdir options[:local] do
20
20
  `git clone #{options[:remote]} .`
21
- if !File.exist?('store.json') || !File.exist?('lock.json')
21
+ unless File.exist?('lock.json')
22
22
  # Should really try to use the Git driver for this
23
- exec 'touch store.json lock.json'
24
- exec 'git add store.json lock.json'
23
+ exec 'touch lock.json'
24
+ exec 'git add lock.json'
25
25
  exec 'git commit -m "Initial commit"'
26
26
  exec 'git push'
27
27
  end
@@ -29,8 +29,10 @@ module TestIds
29
29
  end
30
30
  @local = options[:local]
31
31
  @repo = ::Git.open(options[:local])
32
+ # Get rid of any local edits coming in here, this is only called once at the start
33
+ # of the program generation run.
34
+ # No need to pull latest as that will be done when we obtain a lock.
32
35
  @repo.reset_hard
33
- @repo.pull unless options[:no_pull]
34
36
  end
35
37
 
36
38
  def exec(cmd)
@@ -41,10 +43,12 @@ module TestIds
41
43
  end
42
44
 
43
45
  def publish
44
- write('store.json')
45
- release_lock
46
- repo.commit('Publishing latest store')
47
- repo.push('origin')
46
+ Origen.profile 'Publishing the test IDs store' do
47
+ release_lock
48
+ repo.add # Checkin everything
49
+ repo.commit('Publishing latest store')
50
+ repo.push('origin')
51
+ end
48
52
  end
49
53
 
50
54
  # Writes the data to the given file and pushes to the remote repo
@@ -55,17 +59,21 @@ module TestIds
55
59
  end
56
60
 
57
61
  def get_lock
58
- until available_to_lock?
59
- 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)"
60
- sleep 5
62
+ return if @lock_open
63
+ Origen.profile 'Obtaining test IDs lock' do
64
+ until available_to_lock?
65
+ Origen.log "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)"
66
+ sleep 5
67
+ end
68
+ data = {
69
+ 'user' => User.current.name,
70
+ 'expires' => (Time.now + minutes(5)).to_f
71
+ }
72
+ write('lock.json', JSON.pretty_generate(data))
73
+ repo.commit('Obtaining lock')
74
+ repo.push('origin')
61
75
  end
62
- data = {
63
- 'user' => User.current.name,
64
- 'expires' => (Time.now + minutes(5)).to_f
65
- }
66
- write('lock.json', JSON.pretty_generate(data))
67
- repo.commit('Obtaining lock')
68
- repo.push('origin')
76
+ @lock_open = true
69
77
  end
70
78
 
71
79
  def release_lock
@@ -76,20 +84,17 @@ module TestIds
76
84
  write('lock.json', JSON.pretty_generate(data))
77
85
  end
78
86
 
79
- def with_lock
80
- get_lock
81
- yield
82
- ensure
83
- release_lock
84
- end
85
-
86
87
  def available_to_lock?
87
- repo.pull
88
- if lock_content && lock_user && lock_user != User.current.name
89
- Time.now.to_f > lock_expires
90
- else
91
- true
88
+ result = false
89
+ Origen.profile 'Checking for lock' do
90
+ repo.pull
91
+ if lock_content && lock_user && lock_user != User.current.name
92
+ result = Time.now.to_f > lock_expires
93
+ else
94
+ result = true
95
+ end
92
96
  end
97
+ result
93
98
  end
94
99
 
95
100
  def lock_minutes_remaining
@@ -0,0 +1,12 @@
1
+ require 'origen'
2
+ module Origen
3
+ class <<self
4
+ # Override the Origen.reset_interface method to clear out the TestIds
5
+ # configuration, so that it doesn't carry over from one flow to the next
6
+ alias_method :_orig_reset_interface, :reset_interface
7
+ def reset_interface(options = {})
8
+ TestIds.send(:clear_configuration_id)
9
+ _orig_reset_interface(options)
10
+ end
11
+ end
12
+ end
@@ -5,8 +5,8 @@ module OrigenTesters
5
5
  # test numbers
6
6
  alias_method :_orig_test, :test
7
7
  def test(instance, options = {})
8
- unless TestIds.config.empty?
9
- TestIds.allocator.allocate(instance, options)
8
+ if TestIds.configured?
9
+ TestIds.current_configuration.allocator.allocate(instance, options)
10
10
  end
11
11
  _orig_test(instance, options)
12
12
  end
@@ -0,0 +1,12 @@
1
+ module TestIds
2
+ class ShutdownHandler
3
+ include Origen::PersistentCallbacks
4
+
5
+ def on_origen_shutdown
6
+ TestIds.send(:on_origen_shutdown)
7
+ end
8
+ end
9
+ # Instantiate an instance of this class immediately when this file is loaded, this object will
10
+ # then listen for the remainder of the Origen thread
11
+ ShutdownHandler.new
12
+ end
data/lib/test_ids.rb CHANGED
@@ -19,52 +19,136 @@ module TestIds
19
19
  end
20
20
 
21
21
  class <<self
22
- def store
23
- unless @configuration
24
- fail 'The test ID generator has to be configured before you can start using it'
25
- end
26
- @store ||= Store.new
22
+ def current_configuration
23
+ configuration(@configuration_id)
24
+ end
25
+
26
+ def configuration(id)
27
+ return @configuration[id] if @configuration && @configuration[id]
28
+ fail('You have to create the configuration first before you can access it')
29
+ end
30
+ alias_method :config, :configuration
31
+
32
+ def configure(id = nil, options = {})
33
+ id, options = nil, id if id.is_a?(Hash)
34
+
35
+ @configuration_id = id || options[:id] || :not_specified
36
+
37
+ @configuration ||= {}
38
+
39
+ return if @configuration[@configuration_id]
40
+
41
+ @configuration[@configuration_id] = Configuration.new(@configuration_id)
42
+
43
+ config = @configuration[@configuration_id]
44
+
45
+ yield config
46
+
47
+ config.validate!
48
+
49
+ initialize_git
50
+ end
51
+
52
+ def configured?
53
+ !!@configuration_id
27
54
  end
28
55
 
29
- def allocator
30
- unless @configuration
31
- fail 'The test ID generator has to be configured before you can start using it'
56
+ def initialize_git
57
+ @git_initialized ||= begin
58
+ if repo
59
+ @git = Git.new(local: git_database_dir, remote: repo)
60
+ git.get_lock if on_completion == :save
61
+ end
62
+ true
32
63
  end
33
- @allocator ||= Allocator.new
34
64
  end
35
65
 
36
- def configuration
37
- if block_given?
38
- configure do |config|
39
- yield config
66
+ # Returns a full path to the database file for the given id, returns nil if
67
+ # git storage has not been enabled
68
+ def database_file(id)
69
+ if repo && on_completion == :save
70
+ if id == :not_specified
71
+ f = 'store.json'
72
+ else
73
+ f = "store_#{id.to_s.downcase}.json"
40
74
  end
41
- else
42
- @configuration ||
43
- fail('You have to create the configuration first before you can access it')
75
+ "#{git_database_dir}/#{f}"
44
76
  end
45
77
  end
46
- alias_method :config, :configuration
47
78
 
48
- def configure
79
+ def git_database_dir
80
+ @git_database_dir ||= begin
81
+ d = "#{Origen.app.imports_directory}/test_ids/#{Pathname.new(repo).basename}"
82
+ FileUtils.mkdir_p(d)
83
+ d
84
+ end
85
+ end
86
+
87
+ def git
88
+ @git
89
+ end
90
+
91
+ def repo=(val)
92
+ return if @repo && @repo == val
93
+ if @repo && @repo != val
94
+ fail 'You can only use a single test ids repository per program generation run, one per application is recommended'
95
+ end
96
+ if @configuration
97
+ fail 'TestIds.repo must be set before creating the first configuration'
98
+ end
99
+ @repo = val
100
+ end
101
+
102
+ def repo
103
+ @repo
104
+ end
105
+
106
+ # Returns what should be done with the database for the given configuration
107
+ # at the end, :save (the default) or :discard.
108
+ #
109
+ # If a repo has not been specified, then this attribute has no effect and the
110
+ # data will always be discarded.
111
+ def on_completion
112
+ @on_completion || :save
113
+ end
114
+
115
+ def on_completion=(val)
116
+ return if @on_completion && @on_completion == val
117
+ if @on_completion && @on_completion != val
118
+ fail 'You can only use a single setting for on_completion per program generation run'
119
+ end
49
120
  if @configuration
50
- fail "You can't modify an existing test IDs configuration"
121
+ fail 'TestIds.on_completion must be set before creating the first configuration'
51
122
  end
52
- @configuration = Configuration.new
53
- yield @configuration
54
- @configuration.validate!
55
- allocator.prepare
123
+ unless %w(save discard).include?(val.to_s)
124
+ fail 'on_completion must be set to either :save or :discard'
125
+ end
126
+ @on_completion = val.to_sym
56
127
  end
57
128
 
58
129
  private
59
130
 
131
+ def on_origen_shutdown
132
+ unless testing?
133
+ if repo && on_completion == :save
134
+ @configuration.each do |id, config|
135
+ config.allocator.save
136
+ end
137
+ git.publish
138
+ end
139
+ end
140
+ end
141
+
60
142
  # For testing, clears all instances including the configuration
61
143
  def reset
62
144
  @git = nil
63
- @store = nil
64
- @allocator = nil
65
145
  @configuration = nil
66
146
  end
67
147
 
148
+ def clear_configuration_id
149
+ @configuration_id = nil
150
+ end
151
+
68
152
  def testing=(val)
69
153
  @testing = val
70
154
  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: 0.2.1
4
+ version: 0.3.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: 2016-09-06 00:00:00.000000000 Z
11
+ date: 2016-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -69,7 +69,9 @@ files:
69
69
  - lib/test_ids/bin_array.rb
70
70
  - lib/test_ids/configuration.rb
71
71
  - lib/test_ids/git.rb
72
+ - lib/test_ids/origen/origen.rb
72
73
  - lib/test_ids/origen_testers/flow.rb
74
+ - lib/test_ids/shutdown_handler.rb
73
75
  - lib/test_ids_dev/dut.rb
74
76
  - lib/test_ids_dev/interface.rb
75
77
  - program/prb1.rb
@@ -96,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
98
  version: 1.8.11
97
99
  requirements: []
98
100
  rubyforge_project:
99
- rubygems_version: 2.5.1
101
+ rubygems_version: 2.2.2
100
102
  signing_key:
101
103
  specification_version: 4
102
104
  summary: Origen plugin to assign and track test program bins and test numbers