test_ids 0.2.1 → 0.3.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: 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