furnish-ip 0.0.3 → 0.1.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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjEyYTIzYTc1ZjYxNTI2YTU0NTZlODMwMDE4MjJiYzliNDMxZDUwNA==
5
+ data.tar.gz: !binary |-
6
+ MjdhMmIxMjU0YTA2MGU0NDMxMDI3YmI4M2Q3NmY2NTBjMGVlZDlmYQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YTllZWEwMDU2ZDNhZGY3YWIwNWY5MjEyYjgyNDEyMDI0ZDllZTM2ZGVkNzBj
10
+ YmQ3MmFjOTJiZWMxYzg0MzNiOTNkYjM0YmNiZWQxNWEzZDhkNDUwMDVjNDRj
11
+ YThmNDZlYjFmZjc2MmE0YmE2MjdjNGEwZWVjYTg2OTIwMTVmY2U=
12
+ data.tar.gz: !binary |-
13
+ ZmQyYzA3ZjE2M2I2YzQ0MzM3ODVlZjE1MmE5ZDk1YTUxMmVhMGZiOWVkM2U0
14
+ MGE3MjFhOTIyMTNlODI5NjA2MTU4NWQ1ZjEzNDc3ODcxOGQ4ZWY2MWY4ZGVm
15
+ OTc2Y2YyZDgwOWI2MWM1Y2VkNjliMGRhZDNhN2NiYmNhMWNmZDE=
@@ -1,3 +1,31 @@
1
+ * 0.1.0 (04/10/2013)
2
+ * Now supports Furnish 0.1.0, include protocol and property definitions and
3
+ all Provisioners inherit from Furnish::Provisioner::API. Recovery is still
4
+ unsupported at this time.
5
+ * Furnish::IP API changes:
6
+ * #unused_ip now takes an optional argument -- if a group name is supplied,
7
+ saves it to the group list and allocates it before returning it.
8
+ * #replace_group is sugar to ensure the group for a given name is entirely
9
+ swapped out with a provided group. Does not modify allocations.
10
+ * #assign_group_ips no longer takes a splatted list, requires
11
+ set/array/single item. Converted to set before injecting, returns set it
12
+ injected.
13
+ * #assign_group_ips now has an optional third argument. When true, will
14
+ attempt to determine if what it added modified the counts of allocated
15
+ and the group. If these numbers did not change after addition, will
16
+ raise. Used in the above unused_ip changes to try and get close to atomic
17
+ changes.
18
+ * #remove_from_group subtracts the set of ips from the group.
19
+ * #deallocate removes an IP from the allocated set.
20
+ * Both IP and AutoIP provisioners now track what IPs that specific
21
+ provisioner is responsible for. On shutdown, they will remove only those
22
+ IPs from the group. If the group is empty at that point, the group will be
23
+ destroyed.
24
+ * AutoIP had an issue which was surfaced by the above fix where two AutoIP
25
+ provisioners would compete for address space and end up trying to add the
26
+ same IPs, resulting in a number of allocated IPs that were less than
27
+ requested. Testing indicates this problem is resolved, but issues may still
28
+ arise.
1
29
  * 0.0.3 (03/25/2013)
2
30
  * Several fixes around the encoding of IP addresses -- fixes Ruby 2.0.0-p0
3
31
  issues.
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in furnish-ip.gemspec
4
4
  gemspec
5
-
6
- gem 'guard-rake', :git => "https://github.com/erikh/guard-rake", :branch => "failure_ok"
data/Guardfile CHANGED
@@ -5,6 +5,6 @@ guard 'minitest' do
5
5
  watch(%r!^test/(?:mt_cases|helper)\.rb!) { "test" }
6
6
  end
7
7
 
8
- guard 'rake', :failure_ok => true, :run_on_all => false, :task => 'rdoc_cov' do
8
+ guard 'rake', :run_on_all => false, :task => 'rdoc_cov' do
9
9
  watch(%r!^lib/(.*)([^/]+)\.rb!)
10
10
  end
@@ -17,13 +17,13 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_dependency 'furnish', '~> 0.0.4'
21
- gem.add_dependency 'palsy', '~> 0.0.2'
20
+ gem.add_dependency 'furnish', '~> 0.1.0'
21
+ gem.add_dependency 'palsy', '~> 0.0.4'
22
22
 
23
23
  gem.add_development_dependency 'rake'
24
24
  gem.add_development_dependency 'minitest', '~> 4.5.0'
25
25
  gem.add_development_dependency 'guard-minitest'
26
- gem.add_development_dependency 'guard-rake'
26
+ gem.add_development_dependency 'guard-rake', '~> 0.0.8'
27
27
  gem.add_development_dependency 'rdoc', '~> 4'
28
28
  gem.add_development_dependency 'rb-fsevent'
29
29
  gem.add_development_dependency 'simplecov'
@@ -56,6 +56,13 @@ module Furnish # :nodoc:
56
56
  allocated.add(ip.encode("UTF-8"))
57
57
  end
58
58
 
59
+ #
60
+ # Deallocates IPs from the global allocation pool. Always succeeds.
61
+ #
62
+ def deallocate(ip)
63
+ allocated.delete(ip.encode("UTF-8"))
64
+ end
65
+
59
66
  #
60
67
  # Predicate to determine whether or not an IP is already allocated.
61
68
  #
@@ -68,9 +75,11 @@ module Furnish # :nodoc:
68
75
  # un-used IP is. Will raise ArgumentError if #new is not provided with an
69
76
  # IPAddr object (see the documentation there for details).
70
77
  #
78
+ # If a name is supplied, it will add it to the group IP registry for that name.
79
+ #
71
80
  # Will raise RuntimeError if the subnet is exhausted.
72
81
  #
73
- def unused_ip
82
+ def unused_ip(name=nil)
74
83
  unless subnet
75
84
  raise ArgumentError, "#{self.class}#unused_ip requires an IPAddr object to work"
76
85
  end
@@ -82,7 +91,12 @@ module Furnish # :nodoc:
82
91
  subnet_range.count.times do
83
92
  this_ip = net.to_s.encode("UTF-8")
84
93
 
85
- return this_ip unless allocated.include?(this_ip)
94
+ begin
95
+ unless allocated.include?(this_ip)
96
+ return name ? assign_group_ips(name, this_ip, true).first : this_ip
97
+ end
98
+ rescue
99
+ end
86
100
 
87
101
  net = net.succ
88
102
 
@@ -102,20 +116,57 @@ module Furnish # :nodoc:
102
116
  groups[name] || Set.new
103
117
  end
104
118
 
119
+ #
120
+ # Overwrite a group for name with a given group.
121
+ #
122
+ def replace_group(name, group)
123
+ groups[name] = group
124
+ end
125
+
105
126
  #
106
127
  # Assign one or more ips to a group. This method is additive, so multiple
107
128
  # calls will grow the group, not replace it.
108
129
  #
109
- def assign_group_ips(name, *ips)
130
+ def assign_group_ips(name, ips, raise_if_exists=false)
110
131
  group = group_ips(name)
111
132
 
133
+ if ips.kind_of?(Array)
134
+ ips = Set[*ips]
135
+ elsif !ips.kind_of?(Set)
136
+ ips = Set[ips]
137
+ end
138
+
139
+ c_allocated = allocated.count
140
+ c_group = group.count
141
+
112
142
  ips.each do |ip|
113
143
  utf8_ip = ip.encode("UTF-8")
114
144
  allocated.add(utf8_ip)
115
145
  group.add(utf8_ip)
116
146
  end
117
147
 
118
- groups[name] = group
148
+ if raise_if_exists
149
+ raise unless group.count == c_group + ips.count && allocated.count == c_allocated + ips.count
150
+ end
151
+
152
+ replace_group(name, group)
153
+
154
+ return ips
155
+ end
156
+
157
+ #
158
+ # Remove the IPs from the group provided by name, also deallocates them.
159
+ #
160
+ def remove_from_group(name, ips)
161
+ group = group_ips(name)
162
+
163
+ ips.each do |ip|
164
+ utf8_ip = ip.encode("UTF-8")
165
+ deallocate(utf8_ip)
166
+ group.delete(utf8_ip)
167
+ end
168
+
169
+ replace_group(name, group)
119
170
 
120
171
  return ips
121
172
  end
@@ -127,7 +178,7 @@ module Furnish # :nodoc:
127
178
  group = group_ips(name)
128
179
 
129
180
  group.each do |ip|
130
- allocated.delete(ip)
181
+ deallocate(ip)
131
182
  end
132
183
 
133
184
  groups.delete(name)
@@ -1,6 +1,6 @@
1
1
  module Furnish
2
2
  class IP
3
3
  # Version for furnish-ip
4
- VERSION = "0.0.3"
4
+ VERSION = "0.1.0"
5
5
  end
6
6
  end
@@ -1,3 +1,4 @@
1
+ require 'furnish/provisioners/api'
1
2
  require 'furnish/ip'
2
3
  require 'set'
3
4
 
@@ -9,42 +10,87 @@ module Furnish # :nodoc:
9
10
  # is that this will be chained to another provisioner who would accept it
10
11
  # as input during startup.
11
12
  #
12
- class AutoIP
13
+ class AutoIP < API
13
14
  ##
14
- # The name of the provisioner group, set at scheduling time.
15
- attr_accessor :name
15
+ # :attr: ip
16
+ #
17
+ # A Furnish::IP registry object. If a subnet is not assigned to this
18
+ # object (see Furnish::IP#new), ArgumentError will be raised when
19
+ # attempting to generate IP addresses.
20
+ #
21
+ furnish_property :ip, "A Furnish::IP registry object", Furnish::IP
16
22
 
17
23
  ##
18
- # Create the provisioner. Takes a Furnish::IP object that has subnet
19
- # semantics (see Furnish::IP#new for more information) and a number of
20
- # addresses to allocate, default 1.
21
- def initialize(ip, number_of_addresses=1)
22
- @ip = ip
23
- @number_of_addresses = number_of_addresses
24
+ # :attr: number_of_addresses
25
+ #
26
+ # An integer value specifying the number of addresses to allocate at
27
+ # provisioning time.
28
+ #
29
+ furnish_property :number_of_addresses, "An integer indicating the number of addresses to generate", Integer
30
+
31
+ configure_startup do
32
+ accepts_from_any true
33
+ yields :ips, "Set of strings of recorded IP addresses", Set
34
+ end
35
+
36
+ configure_shutdown do
37
+ accepts_from_any true
38
+ end
39
+
40
+ ##
41
+ # Create the provisioner, requires :ip be passed and referring to a
42
+ # Furnish::IP object with subnet semantics (see Furnish::IP#new), and
43
+ # :number_of_addresses can also be supplied or will default to 1.
44
+ def initialize(args)
45
+ super
46
+
47
+ unless ip
48
+ raise ArgumentError, "A Furnish::IP object must be provided"
49
+ end
50
+
51
+ unless ip.subnet
52
+ raise ArgumentError, "The Furnish::IP object must have a subnet associated"
53
+ end
54
+
55
+ @number_of_addresses ||= 1
24
56
  end
25
57
 
26
58
  ##
27
59
  # Allocate addresses and forward them on to the next provisioner. Uses
28
- # the provisioner group name as the key for the address set.
29
- def startup(*args)
30
- @number_of_addresses.times do
31
- @ip.assign_group_ips(name, @ip.unused_ip)
60
+ # the provisioner group name as the key for the address set. Fills key
61
+ # :ips with a Set of IP addresses.
62
+ def startup(args={})
63
+ @controlled_ips = Set.new
64
+
65
+ number_of_addresses.times do
66
+ this_ip = ip.unused_ip(furnish_group_name)
67
+ @controlled_ips.add(this_ip)
32
68
  end
33
69
 
34
- return @ip.group_ips(name)
70
+ return({ :ips => ip.group_ips(furnish_group_name) })
35
71
  end
36
72
 
37
73
  ##
38
- # Release the IP addresses back to the allocator.
39
- def shutdown
40
- @ip.decommission_group(name)
41
- return true
74
+ # Release the IP addresses back to the allocator. Only releases the IPs
75
+ # that were allocated by this specific provisioner. Destroys the group if
76
+ # it's empty after releasing.
77
+ #
78
+ def shutdown(args={ })
79
+ if @controlled_ips
80
+ ip.remove_from_group(furnish_group_name, @controlled_ips)
81
+ end
82
+
83
+ if ip.group_ips(furnish_group_name).empty?
84
+ ip.decommission_group(furnish_group_name)
85
+ end
86
+
87
+ return { }
42
88
  end
43
89
 
44
90
  ##
45
91
  # Display the allocated addresses for this group.
46
92
  def report
47
- @ip.group_ips(name).to_a
93
+ ip.group_ips(furnish_group_name).to_a rescue []
48
94
  end
49
95
  end
50
96
  end
@@ -1,49 +1,74 @@
1
+ require 'furnish/provisioners/api'
1
2
  require 'furnish/ip'
2
3
  require 'set'
3
4
 
4
5
  module Furnish # :nodoc:
5
6
  module Provisioner # :nodoc:
6
7
  #
7
- # Static Provisioner against the Furnish::IP registry.
8
+ # Static Provisioner against the Furnish::IP registry. Place this after
9
+ # something that yields an IP address to record it in the registry under
10
+ # the provisioner group's name.
8
11
  #
9
- class IP
12
+ class IP < API
10
13
  ##
11
- # The name of the provisioner group, set at scheduling time.
12
- attr_accessor :name
14
+ # :attr: ip
15
+ #
16
+ # A Furnish::IP object.
17
+ #
18
+ furnish_property :ip, "A Furnish::IP registry object", Furnish::IP
19
+
20
+ configure_startup do
21
+ requires :ips, "Set of strings of IP addresses", Set
22
+ yields :ips, "Set of strings of recorded IP addresses", Set
23
+ end
24
+
25
+ configure_shutdown do
26
+ accepts_from_any true
27
+ end
13
28
 
14
- ##
15
29
  #
16
- # Create the provisioner. Takes a Furnish::IP object, and uses no
17
- # auto-allocation features.
30
+ # Create the provisioner, requires :ip be passed and referring to a
31
+ # Furnish::IP object.
18
32
  #
19
- def initialize(ip)
20
- @ip = ip
33
+ def initialize(args)
34
+ super
35
+
36
+ unless ip
37
+ raise ArgumentError, "A Furnish::IP object must be provided"
38
+ end
21
39
  end
22
40
 
23
41
  ##
24
- # Allocate the results passed to the argument list (presumably from a
25
- # previously-run provisioner) in a Furnish::IP group named after the name
26
- # of the provisioning group.
42
+ # Allocate the :ips set passed in to a Furnish::IP group named after the
43
+ # provisioning group.
27
44
  #
28
- # Returns the set of IP addresses.
45
+ # Returns the set of IP addresses in :ips.
29
46
  #
30
- def startup(*args)
31
- @ip.assign_group_ips(name, *args.flatten)
32
- return @ip.group_ips(name)
47
+ def startup(args={})
48
+ @controlled_ips = args[:ips]
49
+ ip.assign_group_ips(furnish_group_name, @controlled_ips)
50
+ return({ :ips => ip.group_ips(furnish_group_name) })
33
51
  end
34
52
 
35
53
  ##
36
54
  # Releases the allocated addresses.
37
55
  #
38
- def shutdown
39
- @ip.decommission_group(name)
40
- return true
56
+ def shutdown(args={})
57
+ if @controlled_ips
58
+ ip.remove_from_group(furnish_group_name, @controlled_ips)
59
+ end
60
+
61
+ if ip.group_ips(furnish_group_name).empty?
62
+ ip.decommission_group(furnish_group_name)
63
+ end
64
+
65
+ return({ })
41
66
  end
42
67
 
43
68
  ##
44
69
  # Display the allocated addresses for this group.
45
70
  def report
46
- @ip.group_ips(name).to_a
71
+ ip.group_ips(furnish_group_name).to_a rescue []
47
72
  end
48
73
  end
49
74
  end
@@ -3,11 +3,55 @@ require 'helper'
3
3
  class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
4
4
  def setup
5
5
  super
6
+ @klass = Furnish::Provisioner::AutoIP
6
7
  @ip = Furnish::IP.new("127.0.0.1/24")
7
8
  end
8
9
 
9
10
  def make_provisioner(num=1)
10
- Furnish::Provisioner::AutoIP.new(@ip, num)
11
+ @klass.new(:ip => @ip, :number_of_addresses => num)
12
+ end
13
+
14
+ def test_constructor
15
+ assert_raises(ArgumentError) { @klass.new({}) }
16
+ assert_raises(ArgumentError) { @klass.new(:ip => Furnish::IP.new) }
17
+ prov = @klass.new(:ip => Furnish::IP.new("10.10.10.0/8"))
18
+ assert_equal(1, prov.number_of_addresses)
19
+ end
20
+
21
+ def test_properties
22
+ assert_equal(
23
+ {
24
+ :ip => {
25
+ :description => "A Furnish::IP registry object",
26
+ :type => Furnish::IP
27
+ },
28
+ :number_of_addresses => {
29
+ :description => "An integer indicating the number of addresses to generate",
30
+ :type => Integer
31
+ }
32
+ },
33
+ @klass.furnish_properties
34
+ )
35
+ end
36
+
37
+ def test_protocol
38
+ assert_equal(
39
+ {
40
+ :ips => {
41
+ :description => "Set of strings of recorded IP addresses",
42
+ :type => Set
43
+ }
44
+ },
45
+ @klass.startup_protocol[:yields]
46
+ )
47
+
48
+ assert_empty(@klass.startup_protocol[:requires])
49
+ assert_empty(@klass.startup_protocol[:accepts])
50
+
51
+ [:accepts, :yields, :requires].each { |x| assert_empty(@klass.shutdown_protocol[x]) }
52
+
53
+ assert(@klass.startup_protocol[:accepts_from_any])
54
+ assert(@klass.shutdown_protocol[:accepts_from_any])
11
55
  end
12
56
 
13
57
  def test_basic_provision
@@ -22,7 +66,7 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
22
66
 
23
67
  first_ip = @ip.group_ips("test1").first
24
68
 
25
- assert_equal("test1", provisioner.name, "name reflects provisioner name")
69
+ assert_equal("test1", provisioner.furnish_group_name, "name reflects provisioner name")
26
70
  assert_equal([first_ip], provisioner.report, "report reflects provisioned IPs")
27
71
 
28
72
  sched.schedule_provision("test2", make_provisioner(10), [])
@@ -51,4 +95,34 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
51
95
  assert_solved("test1")
52
96
  assert_equal(first_ip, @ip.group_ips("test1").first, "provisioner re-uses deprovisioned IP addresses")
53
97
  end
98
+
99
+ def test_multi_provision
100
+ first = make_provisioner(5)
101
+ second = make_provisioner(5)
102
+
103
+ sched.s("first", first)
104
+ sched.s("second", second)
105
+ sched.wait_for("first", "second")
106
+ assert_solved("first")
107
+ assert_solved("second")
108
+ assert_equal(5, @ip.group_ips("first").count)
109
+ assert_equal(5, @ip.group_ips("second").count)
110
+ assert_equal(10, @ip.allocated.count)
111
+
112
+ sched.deprovision_group("first")
113
+
114
+ assert_equal(5, @ip.allocated.count)
115
+
116
+ sched.deprovision_group("second")
117
+
118
+ assert_equal(0, @ip.allocated.count)
119
+
120
+ sched.s("both", [first, second])
121
+ sched.wait_for("both")
122
+ assert_equal(10, @ip.group_ips("both").count)
123
+ assert_equal(10, @ip.allocated.count)
124
+ sched.teardown
125
+ assert_equal(0, @ip.group_ips("both").count)
126
+ assert_equal(0, @ip.allocated.count)
127
+ end
54
128
  end
@@ -72,22 +72,22 @@ class TestIPLib < Furnish::TestCase
72
72
  allocated.add(ip_arg)
73
73
 
74
74
  assert_equal(
75
- [ip_arg],
75
+ Set[ip_arg],
76
76
  ip.assign_group_ips("foo", ip_arg),
77
- "single argument is return as an array"
77
+ "single argument is returned as a set"
78
78
  )
79
79
 
80
80
  assert_equal(Set[ip_arg], ip.group_ips("foo"), "returned as set from group_ips")
81
81
 
82
82
  unused_ip = ip.unused_ip
83
- ip_arg = [unused_ip, unused_ip.succ, unused_ip.succ.succ]
83
+ ip_arg = Set[unused_ip, unused_ip.succ, unused_ip.succ.succ]
84
84
 
85
85
  ip_arg.each { |i| allocated.add(i) }
86
86
 
87
87
  assert_equal(
88
88
  ip_arg,
89
- ip.assign_group_ips("bar", *ip_arg),
90
- "array is returned when multiple arguments passed"
89
+ ip.assign_group_ips("bar", ip_arg.to_a),
90
+ "set is returned when array passed"
91
91
  )
92
92
 
93
93
  assert_equal(Set[*ip_arg], ip.group_ips("bar"), "returned as set from group_ips")
@@ -1,19 +1,31 @@
1
1
  require 'helper'
2
2
  require 'ipaddr'
3
+ require 'furnish/provisioners/api'
4
+ require 'set'
3
5
 
4
- class IPReturningProvisioner
5
- attr_accessor :name
6
+ class IPReturningProvisioner < Furnish::Provisioner::API
7
+ furnish_property :ips, "An array of IP addresses as strings", Array
6
8
 
7
- def initialize(*ips)
8
- @ips = ips
9
+ configure_startup do
10
+ accepts_from_any true
11
+ yields :ips, "A set of IP addresses as strings", Set
9
12
  end
10
13
 
11
- def startup(*args)
12
- return @ips
14
+ configure_shutdown do
15
+ accepts_from_any true
13
16
  end
14
17
 
15
- def shutdown
16
- return true
18
+ def initialize(args)
19
+ super
20
+ @ips = Set[*ips]
21
+ end
22
+
23
+ def startup(args={})
24
+ return({ :ips => ips })
25
+ end
26
+
27
+ def shutdown(args={})
28
+ return({ })
17
29
  end
18
30
 
19
31
  def report
@@ -24,16 +36,62 @@ end
24
36
  class TestIPProvisioner < Furnish::RunningSchedulerTestCase
25
37
  def setup
26
38
  super
39
+ @klass = Furnish::Provisioner::IP
27
40
  @ip = Furnish::IP.new
28
41
  end
29
42
 
30
43
  def make_provisioner(*ips)
31
44
  [
32
- IPReturningProvisioner.new(*ips),
33
- Furnish::Provisioner::IP.new(@ip)
45
+ IPReturningProvisioner.new(:ips => ips),
46
+ @klass.new(:ip => @ip)
34
47
  ]
35
48
  end
36
49
 
50
+ def test_constructor
51
+ assert_raises(ArgumentError) { @klass.new({ }) }
52
+ @klass.new(:ip => Furnish::IP.new)
53
+ end
54
+
55
+ def test_properties
56
+ assert_equal(
57
+ {
58
+ :ip => {
59
+ :description => "A Furnish::IP registry object",
60
+ :type => Furnish::IP
61
+ }
62
+ },
63
+ @klass.furnish_properties
64
+ )
65
+ end
66
+
67
+ def test_protocol
68
+ assert_equal(
69
+ {
70
+ :ips => {
71
+ :description => "Set of strings of IP addresses",
72
+ :type => Set
73
+ }
74
+ },
75
+ @klass.startup_protocol[:requires]
76
+ )
77
+
78
+ assert_equal(
79
+ {
80
+ :ips => {
81
+ :description => "Set of strings of recorded IP addresses",
82
+ :type => Set
83
+ }
84
+ },
85
+ @klass.startup_protocol[:yields]
86
+ )
87
+
88
+ assert_empty(@klass.startup_protocol[:accepts])
89
+
90
+ [:accepts, :yields, :requires].each { |x| assert_empty(@klass.shutdown_protocol[x]) }
91
+
92
+ assert(@klass.shutdown_protocol[:accepts_from_any])
93
+ end
94
+
37
95
  def test_basic_provision
38
96
  ipaddr = IPAddr.new("127.0.0.1/24")
39
97
  ips = (0..4).map { ipaddr = ipaddr.succ; ipaddr.to_s }
@@ -48,7 +106,7 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
48
106
  assert_equal(count, @ip.group_ips("test1").count, "#{count} IPs were allocated")
49
107
  assert_equal(count, @ip.allocated.count, "#{count} IPs were allocated")
50
108
 
51
- assert_equal("test1", provisioner.last.name, "name reflects group name")
109
+ assert_equal("test1", provisioner.last.furnish_group_name, "name reflects group name")
52
110
  assert_equal(ips, provisioner.last.report, "report reflects ip list")
53
111
 
54
112
  ips = (0..4).map { ipaddr = ipaddr.succ; ipaddr.to_s }
@@ -74,4 +132,41 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
74
132
  assert_empty(@ip.group_ips("test1"), "torn down group is empty")
75
133
  assert_equal(0, @ip.allocated.count, "count is zero after deprovisioning all groups")
76
134
  end
135
+
136
+ def test_multi_provision
137
+ ipaddr = IPAddr.new("127.0.0.1/24")
138
+ first_ips = (0..4).map { ipaddr = ipaddr.succ; ipaddr.to_s }
139
+ first = make_provisioner(*first_ips)
140
+ second_ips = (0..4).map { ipaddr = ipaddr.succ; ipaddr.to_s }
141
+ second = make_provisioner(*second_ips)
142
+
143
+ sched.s("first", first)
144
+ sched.wait_for("first")
145
+ assert_solved("first")
146
+ assert_equal(first_ips.count, @ip.group_ips("first").count, "#{first_ips.count} IPs were allocated")
147
+ assert_equal(first_ips.count, @ip.allocated.count, "#{first_ips.count} IPs were allocated")
148
+ sched.deprovision_group("first")
149
+ assert_equal(0, @ip.group_ips("first").count, "count is zero after deprovision")
150
+ assert_equal(0, @ip.allocated.count, "count is zero after deprovision")
151
+
152
+ sched.s("second", second)
153
+ sched.wait_for("second")
154
+ assert_solved("second")
155
+ assert_equal(second_ips.count, @ip.group_ips("second").count, "#{second_ips.count} IPs were allocated")
156
+ assert_equal(second_ips.count, @ip.allocated.count, "#{second_ips.count} IPs were allocated")
157
+ sched.deprovision_group("second")
158
+ assert_equal(0, @ip.group_ips("second").count, "count is zero after deprovision")
159
+ assert_equal(0, @ip.allocated.count, "count is zero after deprovision")
160
+
161
+ sched.s("test1", first + second)
162
+ sched.wait_for("test1")
163
+
164
+ assert_solved("test1")
165
+ total = first_ips.count + second_ips.count
166
+ assert_equal(total, @ip.group_ips("test1").count, "#{total} IPs were allocated")
167
+ assert_equal(total, @ip.allocated.count, "#{total} IPs were allocated")
168
+ sched.deprovision_group("test1")
169
+ assert_equal(0, @ip.group_ips("test1").count, "count is zero after deprovision")
170
+ assert_equal(0, @ip.allocated.count, "count is zero after deprovision")
171
+ end
77
172
  end
metadata CHANGED
@@ -1,52 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: furnish-ip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Erik Hollensbe
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-25 00:00:00.000000000 Z
11
+ date: 2013-04-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: furnish
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: 0.0.4
19
+ version: 0.1.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
29
- version: 0.0.4
26
+ version: 0.1.0
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: palsy
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
37
- version: 0.0.2
33
+ version: 0.0.4
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
45
- version: 0.0.2
40
+ version: 0.0.4
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rake
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: minitest
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: guard-minitest
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,23 +83,20 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: guard-rake
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ~>
100
88
  - !ruby/object:Gem::Version
101
- version: '0'
89
+ version: 0.0.8
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ~>
108
95
  - !ruby/object:Gem::Version
109
- version: '0'
96
+ version: 0.0.8
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: rdoc
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ~>
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ~>
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: rb-fsevent
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ! '>='
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ! '>='
140
123
  - !ruby/object:Gem::Version
@@ -142,7 +125,6 @@ dependencies:
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: simplecov
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
129
  - - ! '>='
148
130
  - !ruby/object:Gem::Version
@@ -150,7 +132,6 @@ dependencies:
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
136
  - - ! '>='
156
137
  - !ruby/object:Gem::Version
@@ -180,27 +161,26 @@ files:
180
161
  - test/test_ip_provisioner.rb
181
162
  homepage: ''
182
163
  licenses: []
164
+ metadata: {}
183
165
  post_install_message:
184
166
  rdoc_options: []
185
167
  require_paths:
186
168
  - lib
187
169
  required_ruby_version: !ruby/object:Gem::Requirement
188
- none: false
189
170
  requirements:
190
171
  - - ! '>='
191
172
  - !ruby/object:Gem::Version
192
173
  version: '0'
193
174
  required_rubygems_version: !ruby/object:Gem::Requirement
194
- none: false
195
175
  requirements:
196
176
  - - ! '>='
197
177
  - !ruby/object:Gem::Version
198
178
  version: '0'
199
179
  requirements: []
200
180
  rubyforge_project:
201
- rubygems_version: 1.8.25
181
+ rubygems_version: 2.0.3
202
182
  signing_key:
203
- specification_version: 3
183
+ specification_version: 4
204
184
  summary: Generic IP allocator for the Furnish provisioning system
205
185
  test_files:
206
186
  - test/helper.rb