furnish 0.1.2 → 0.1.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/furnish.gemspec +2 -2
- data/lib/furnish.rb +9 -0
- data/lib/furnish/protocol.rb +1 -1
- data/lib/furnish/provisioner_group.rb +28 -3
- data/lib/furnish/provisioners/api.rb +12 -1
- data/lib/furnish/provisioners/dummy.rb +4 -91
- data/lib/furnish/provisioners/dummy_include.rb +97 -0
- data/lib/furnish/provisioners/dummy_vm.rb +17 -0
- data/lib/furnish/provisioners/vm.rb +64 -0
- data/lib/furnish/scheduler.rb +8 -1
- data/lib/furnish/test.rb +27 -19
- data/lib/furnish/test/scheduler_runner.rb +53 -0
- data/lib/furnish/version.rb +1 -1
- data/test/helper.rb +1 -2
- data/test/mt_cases.rb +22 -1
- data/test/test_api.rb +1 -1
- data/test/test_dummy.rb +1 -1
- data/test/test_logger.rb +1 -1
- data/test/test_protocol.rb +9 -1
- data/test/test_provisioner_group.rb +27 -1
- data/test/test_provisioner_vm.rb +33 -0
- data/test/test_scheduler_basic.rb +8 -1
- data/test/test_scheduler_serial.rb +2 -1
- data/test/test_scheduler_threaded.rb +2 -1
- data/test/test_vm.rb +1 -1
- metadata +14 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5757619fff0af93f2441893e9e204dc74d7573bc
|
4
|
+
data.tar.gz: e260a91321a8388b4519075209d382ce916678a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76d06e7b7374aca71abeeda91bc4d393b8cc6b7bb7bf7f9a85cd283602b355331acfa91bb668a93643e5886ea55749c9bcae01bdeec36cd2dc731e96d555181f
|
7
|
+
data.tar.gz: f39d5dcf9b1cf280a141b431681ba71ed7b9abb5f580bff6d53c108bb4593c94d6951b6a3530541c0b0bffc6f8d0cccb0777c8ce9d26bd9e84e40661c0947c5f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.1.3 (07/06/2013)
|
2
|
+
* Furnish::Provisioner::VM is a new subclass of API (and therefore should be
|
3
|
+
subclassed), specifically geared to add new functionality for machine
|
4
|
+
provisioners.
|
5
|
+
* Furnish::TestCase is now Furnish::Test and is Minitest 5 based.
|
1
6
|
# 0.1.2 (04/27/2013)
|
2
7
|
* Logger changes:
|
3
8
|
* Fixed: Certain situations with if_debug and the IO proxy would result in
|
data/furnish.gemspec
CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.add_dependency 'palsy', '~> 0.0.4'
|
22
22
|
|
23
|
-
gem.add_development_dependency 'rake'
|
24
|
-
gem.add_development_dependency 'minitest', '~>
|
23
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
gem.add_development_dependency 'minitest', '~> 5.0'
|
25
25
|
gem.add_development_dependency 'guard-minitest'
|
26
26
|
gem.add_development_dependency 'guard-rake', '~> 0.0.8'
|
27
27
|
gem.add_development_dependency 'rdoc', '~> 4'
|
data/lib/furnish.rb
CHANGED
@@ -17,6 +17,14 @@ module Furnish
|
|
17
17
|
#
|
18
18
|
def self.init(database_file)
|
19
19
|
Palsy.change_db(database_file)
|
20
|
+
@initialized = true
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Has furnish been initialized?
|
25
|
+
#
|
26
|
+
def self.initialized?
|
27
|
+
@initialized
|
20
28
|
end
|
21
29
|
|
22
30
|
#
|
@@ -44,6 +52,7 @@ module Furnish
|
|
44
52
|
# have a bad day.
|
45
53
|
#
|
46
54
|
def self.shutdown
|
55
|
+
@initialized = false
|
47
56
|
Palsy.instance.close
|
48
57
|
end
|
49
58
|
end
|
data/lib/furnish/protocol.rb
CHANGED
@@ -195,7 +195,7 @@ module Furnish # :nodoc:
|
|
195
195
|
return self[:accepts_from_any]
|
196
196
|
end
|
197
197
|
|
198
|
-
return
|
198
|
+
return ap.keys.any? { |k| yp.has_key?(k) && ap[k][:type].ancestors.include?(yp[k][:type]) }
|
199
199
|
end
|
200
200
|
|
201
201
|
VALIDATOR_NAMES.each do |vname|
|
@@ -67,6 +67,7 @@ module Furnish
|
|
67
67
|
@dependencies = dependencies.kind_of?(Set) ? dependencies : Set[*dependencies]
|
68
68
|
|
69
69
|
assert_provisioner_protocol(provisioners)
|
70
|
+
run_add_hook(provisioners)
|
70
71
|
|
71
72
|
super(provisioners)
|
72
73
|
end
|
@@ -154,7 +155,7 @@ module Furnish
|
|
154
155
|
end
|
155
156
|
|
156
157
|
unless args.kind_of?(Hash) or force
|
157
|
-
set_recovery(this_prov, i,
|
158
|
+
set_recovery(this_prov, i, shutdown_args)
|
158
159
|
raise ArgumentError,
|
159
160
|
"#{this_prov.class} does not return data that can be consumed by the next provisioner"
|
160
161
|
end
|
@@ -246,12 +247,27 @@ module Furnish
|
|
246
247
|
return result # scheduler will take it from here
|
247
248
|
end
|
248
249
|
|
250
|
+
#
|
251
|
+
# Get a list of vms from provisioners that provide VMs via the ..
|
252
|
+
# Furnish::Provisioner::VM interface.
|
253
|
+
#
|
254
|
+
def vms
|
255
|
+
h = { }
|
256
|
+
|
257
|
+
each do |prov|
|
258
|
+
if prov.respond_to?(:list_vms)
|
259
|
+
h[prov] = prov.list_vms
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
return h
|
264
|
+
end
|
265
|
+
|
249
266
|
protected
|
250
267
|
|
251
268
|
#
|
252
269
|
# Similar to #clean_state, a helper for recovery tracking
|
253
270
|
#
|
254
|
-
|
255
271
|
def set_recovery(prov, index, args=nil)
|
256
272
|
@group_state['provisioner'] = prov
|
257
273
|
@group_state['index'] = index
|
@@ -300,6 +316,15 @@ module Furnish
|
|
300
316
|
return result
|
301
317
|
end
|
302
318
|
|
319
|
+
#
|
320
|
+
# Runs the Furnish::Provisioner::API#added_to_group hook for each provisioner
|
321
|
+
#
|
322
|
+
def run_add_hook(provisioners)
|
323
|
+
provisioners.each do |prov|
|
324
|
+
prov.added_to_group if prov.respond_to?(:added_to_group)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
303
328
|
#
|
304
329
|
# Asserts that all the provisioners can communicate with each other.
|
305
330
|
#
|
@@ -322,7 +347,7 @@ module Furnish
|
|
322
347
|
yielders = [iterator.shift.class]
|
323
348
|
|
324
349
|
while accepting = iterator.shift
|
325
|
-
accepting = accepting.class
|
350
|
+
accepting = accepting.class
|
326
351
|
|
327
352
|
unless yielders.all? { |y| y.respond_to?(protocol_method) }
|
328
353
|
raise ArgumentError, "yielding classes do not implement protocol #{protocol_method} -- cannot continue"
|
@@ -296,6 +296,17 @@ module Furnish # :nodoc:
|
|
296
296
|
end
|
297
297
|
end
|
298
298
|
|
299
|
+
#
|
300
|
+
# This is run when the provisioner is added to a
|
301
|
+
# Furnish::ProvisionerGroup. This is for doing things that would require
|
302
|
+
# the name of the group (such as allocating Palsy objects), but can't be
|
303
|
+
# done in #initialize because the group name isn't known yet.
|
304
|
+
#
|
305
|
+
# Note that #furnish_group_name will be set by the time this hook is run.
|
306
|
+
#
|
307
|
+
def added_to_group
|
308
|
+
end
|
309
|
+
|
299
310
|
#
|
300
311
|
# Called by Furnish::ProvisionerGroup#startup which is itself called by
|
301
312
|
# Furnish::Scheduler#startup. Indicates the resource this provisioner
|
@@ -427,7 +438,7 @@ module Furnish # :nodoc:
|
|
427
438
|
y
|
428
439
|
end +
|
429
440
|
[self.class]
|
430
|
-
)
|
441
|
+
).bytes.inject(0) { |x,y| x += y.ord }
|
431
442
|
end
|
432
443
|
end
|
433
444
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'furnish/provisioners/dummy_include'
|
2
|
+
require 'furnish/provisioners/api'
|
3
|
+
|
1
4
|
module Furnish
|
2
5
|
module Provisioner
|
3
6
|
#
|
@@ -8,97 +11,7 @@ module Furnish
|
|
8
11
|
# code.
|
9
12
|
#
|
10
13
|
class Dummy < API
|
11
|
-
|
12
|
-
# Some dancing around the marshal issues with this provisioner. Note that
|
13
|
-
# after restoration, any delegates you set will no longer exist, so
|
14
|
-
# relying on scheduler persistence is a really bad idea.
|
15
|
-
#++
|
16
|
-
|
17
|
-
# basic Palsy::Object store for stuffing random stuff
|
18
|
-
attr_reader :store
|
19
|
-
|
20
|
-
# order tracking via Palsy::List, delegation makes a breadcrumb here
|
21
|
-
# that's ordered between all provisioners.
|
22
|
-
attr_reader :order
|
23
|
-
|
24
|
-
# arbitrary identifier for Dummy#call_order
|
25
|
-
attr_accessor :id
|
26
|
-
|
27
|
-
#
|
28
|
-
# Construct a Dummy.
|
29
|
-
#
|
30
|
-
def initialize
|
31
|
-
@store = Palsy::Object.new('dummy')
|
32
|
-
@order = Palsy::List.new('dummy_order', 'shared')
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
# used in state transitions to capture run information
|
37
|
-
#
|
38
|
-
def run_state
|
39
|
-
@run_state ||= Palsy::Map.new('dummy_run_state', [self.class.name, respond_to?(:furnish_group_name) ? furnish_group_name : name].join("-"))
|
40
|
-
end
|
41
|
-
|
42
|
-
#
|
43
|
-
# call order is ordering on a per-provisioner group basis, and is used to
|
44
|
-
# validate that groups do indeed execute in the proper order.
|
45
|
-
#
|
46
|
-
def call_order
|
47
|
-
# respond_to? here is to assist with deprecation tests
|
48
|
-
@call_order ||= Palsy::List.new('dummy_order', respond_to?(:furnish_group_name) ? furnish_group_name : name)
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# report shim
|
53
|
-
#
|
54
|
-
def report
|
55
|
-
do_delegate(__method__) do
|
56
|
-
[furnish_group_name, @persist]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
#
|
61
|
-
# startup shim
|
62
|
-
#
|
63
|
-
def startup(args={ })
|
64
|
-
@persist = "floop"
|
65
|
-
do_delegate(__method__) do
|
66
|
-
run_state[__method__] = args
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
#
|
71
|
-
# shutdown shim
|
72
|
-
#
|
73
|
-
def shutdown(args={ })
|
74
|
-
do_delegate(__method__) do
|
75
|
-
run_state[__method__] = args
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
#
|
80
|
-
# Helper to trace calls to this provisioner. Pretty much everything we
|
81
|
-
# care about goes through here.
|
82
|
-
#
|
83
|
-
def do_delegate(meth_name)
|
84
|
-
meth_name = meth_name.to_s
|
85
|
-
|
86
|
-
# indicate we actually did something
|
87
|
-
@store[ [furnish_group_name, meth_name].join("-") ] = Time.now.to_i
|
88
|
-
@order.push(furnish_group_name)
|
89
|
-
call_order.push(id || "unknown")
|
90
|
-
|
91
|
-
yield
|
92
|
-
end
|
93
|
-
|
94
|
-
#
|
95
|
-
# Test the mixin functionality
|
96
|
-
#
|
97
|
-
def make_log
|
98
|
-
if_debug do
|
99
|
-
puts "hello from Dummy"
|
100
|
-
end
|
101
|
-
end
|
14
|
+
include Furnish::Provisioner::DummyInclude
|
102
15
|
end
|
103
16
|
end
|
104
17
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Furnish # :nodoc:
|
2
|
+
module Provisioner # :nodoc:
|
3
|
+
module DummyInclude # :nodoc:
|
4
|
+
#--
|
5
|
+
# Some dancing around the marshal issues with this provisioner. Note that
|
6
|
+
# after restoration, any delegates you set will no longer exist, so
|
7
|
+
# relying on scheduler persistence is a really bad idea.
|
8
|
+
#++
|
9
|
+
|
10
|
+
# basic Palsy::Object store for stuffing random stuff
|
11
|
+
attr_reader :store
|
12
|
+
|
13
|
+
# order tracking via Palsy::List, delegation makes a breadcrumb here
|
14
|
+
# that's ordered between all provisioners.
|
15
|
+
attr_reader :order
|
16
|
+
|
17
|
+
# arbitrary identifier for Dummy#call_order
|
18
|
+
attr_accessor :id
|
19
|
+
|
20
|
+
#
|
21
|
+
# Construct a Dummy.
|
22
|
+
#
|
23
|
+
def initialize
|
24
|
+
@store = Palsy::Object.new('dummy')
|
25
|
+
@order = Palsy::List.new('dummy_order', 'shared')
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# used in state transitions to capture run information
|
30
|
+
#
|
31
|
+
def run_state
|
32
|
+
@run_state ||= Palsy::Map.new('dummy_run_state', [self.class.name, respond_to?(:furnish_group_name) ? furnish_group_name : name].join("-"))
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# call order is ordering on a per-provisioner group basis, and is used to
|
37
|
+
# validate that groups do indeed execute in the proper order.
|
38
|
+
#
|
39
|
+
def call_order
|
40
|
+
# respond_to? here is to assist with deprecation tests
|
41
|
+
@call_order ||= Palsy::List.new('dummy_order', respond_to?(:furnish_group_name) ? furnish_group_name : name)
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# report shim
|
46
|
+
#
|
47
|
+
def report
|
48
|
+
do_delegate(__method__) do
|
49
|
+
[furnish_group_name, @persist]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# startup shim
|
55
|
+
#
|
56
|
+
def startup(args={ })
|
57
|
+
@persist = "floop"
|
58
|
+
do_delegate(__method__) do
|
59
|
+
run_state[__method__] = args
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# shutdown shim
|
65
|
+
#
|
66
|
+
def shutdown(args={ })
|
67
|
+
do_delegate(__method__) do
|
68
|
+
run_state[__method__] = args
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Helper to trace calls to this provisioner. Pretty much everything we
|
74
|
+
# care about goes through here.
|
75
|
+
#
|
76
|
+
def do_delegate(meth_name)
|
77
|
+
meth_name = meth_name.to_s
|
78
|
+
|
79
|
+
# indicate we actually did something
|
80
|
+
@store[ [furnish_group_name, meth_name].join("-") ] = Time.now.to_i
|
81
|
+
@order.push(furnish_group_name)
|
82
|
+
call_order.push(id || "unknown")
|
83
|
+
|
84
|
+
yield
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Test the mixin functionality
|
89
|
+
#
|
90
|
+
def make_log
|
91
|
+
if_debug do
|
92
|
+
puts "hello from Dummy"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'furnish/provisioners/dummy_include'
|
2
|
+
require 'furnish/provisioners/vm'
|
3
|
+
|
4
|
+
module Furnish # :nodoc:
|
5
|
+
module Provisioner # :nodoc:
|
6
|
+
#
|
7
|
+
# Primarily for testing, this is a provisioner that has a basic storage
|
8
|
+
# model.
|
9
|
+
#
|
10
|
+
# In short, unless you're writing tests you should probably never use this
|
11
|
+
# code.
|
12
|
+
#
|
13
|
+
class DummyVM < VM
|
14
|
+
include Furnish::Provisioner::DummyInclude
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'furnish/provisioners/api'
|
2
|
+
|
3
|
+
module Furnish # :nodoc:
|
4
|
+
module Provisioner # :nodoc:
|
5
|
+
#
|
6
|
+
# The VM provisioner API (which inherits from Furnish::Provisioner::API)
|
7
|
+
# just adds a few convenience functions and a tracking database for VM
|
8
|
+
# work. This makes it easy to get the data back you need and an easy,
|
9
|
+
# consistent way to stuff it away when you have data to store.
|
10
|
+
#
|
11
|
+
# See the methods themselves for more information.
|
12
|
+
#
|
13
|
+
class VM < API
|
14
|
+
#
|
15
|
+
# Our database, which won't be available until the provisioner is added
|
16
|
+
# to a ProvisionerGroup.
|
17
|
+
#
|
18
|
+
attr_reader :vm
|
19
|
+
|
20
|
+
#
|
21
|
+
# Hook required by Furnish::ProvisionerGroup#run_add_hook. See
|
22
|
+
# Furnish::Provisioner::API#added_to_group for more information.
|
23
|
+
#
|
24
|
+
def added_to_group
|
25
|
+
@vm = Palsy::Map.new(self.class.name.gsub(/::/, '_').downcase + "_vms", furnish_group_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Add a vm. Takes a name (String) and metadata (Hash).
|
30
|
+
#
|
31
|
+
def add_vm(name, metadata)
|
32
|
+
unless vm
|
33
|
+
raise "Cannot add machine '#{name}' to ungrouped provisioner"
|
34
|
+
end
|
35
|
+
|
36
|
+
unless metadata.kind_of?(Hash)
|
37
|
+
raise ArgumentError, "Metadata must be a kind of Hash!"
|
38
|
+
end
|
39
|
+
|
40
|
+
vm[name] = metadata
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Delete a VM. Takes a name (String).
|
45
|
+
#
|
46
|
+
def remove_vm(name)
|
47
|
+
unless vm
|
48
|
+
raise "Cannot delete machine '#{name}' from ungrouped provisioner"
|
49
|
+
end
|
50
|
+
|
51
|
+
vm.delete(name)
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# List the VMs. If the provisioner is not named (a part of a
|
56
|
+
# Furnish::ProvisionerGroup), will return an empty array.
|
57
|
+
#
|
58
|
+
def list_vms
|
59
|
+
return [] unless vm
|
60
|
+
return vm.keys
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/furnish/scheduler.rb
CHANGED
@@ -46,6 +46,9 @@ module Furnish
|
|
46
46
|
# Instantiate the Scheduler.
|
47
47
|
#
|
48
48
|
def initialize
|
49
|
+
|
50
|
+
raise "Cannot start; Furnish has not been initialized" unless Furnish.initialized?
|
51
|
+
|
49
52
|
@force_deprovision = false
|
50
53
|
@solved_mutex = Mutex.new
|
51
54
|
@serial = false
|
@@ -310,7 +313,11 @@ module Furnish
|
|
310
313
|
# halt the deprovisioning process.
|
311
314
|
#
|
312
315
|
def teardown_group(group_name, wait=true)
|
313
|
-
|
316
|
+
begin
|
317
|
+
wait_for(group_name) if wait
|
318
|
+
rescue => e
|
319
|
+
raise e unless force_deprovision
|
320
|
+
end
|
314
321
|
|
315
322
|
dependent_items = vm.dependencies.partition { |k,v| v.include?(group_name) }.first.map(&:first)
|
316
323
|
|
data/lib/furnish/test.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
require 'minitest
|
1
|
+
require 'minitest'
|
2
|
+
require 'minitest/test'
|
2
3
|
require 'tempfile'
|
3
4
|
require 'furnish'
|
4
5
|
|
5
6
|
module Furnish
|
7
|
+
|
6
8
|
#
|
7
9
|
# Furnish::TestCase is a test harness for testing things with furnish, like
|
8
10
|
# provisioner libraries. It is intended to be consumed by other libraries.
|
@@ -18,20 +20,21 @@ module Furnish
|
|
18
20
|
# log will be presented to the standard error. Otherwise, it is sent a log
|
19
21
|
# file.
|
20
22
|
#
|
21
|
-
class
|
23
|
+
class Test < Minitest::Test
|
22
24
|
def setup # :nodoc:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
unless Furnish.initialized? or (Minitest.respond_to?(:keep_scheduler) and Minitest.keep_scheduler rescue nil)
|
26
|
+
@tempfiles ||= []
|
27
|
+
file = Tempfile.new('furnish_db')
|
28
|
+
@tempfiles.push(file)
|
29
|
+
if ENV["FURNISH_DEBUG"]
|
30
|
+
Furnish.logger = Furnish::Logger.new($stderr, 3)
|
31
|
+
else
|
32
|
+
logfile = Tempfile.new('furnish_log')
|
33
|
+
@tempfiles.push(logfile)
|
34
|
+
Furnish.logger = Furnish::Logger.new(logfile, 3)
|
35
|
+
end
|
36
|
+
Furnish.init(file.path)
|
32
37
|
end
|
33
|
-
Furnish.init(file.path)
|
34
|
-
return file
|
35
38
|
end
|
36
39
|
|
37
40
|
def teardown # :nodoc:
|
@@ -39,9 +42,11 @@ module Furnish
|
|
39
42
|
Furnish.logger.close
|
40
43
|
end
|
41
44
|
|
42
|
-
Furnish.
|
43
|
-
|
44
|
-
file
|
45
|
+
if Furnish.initialized? and !(Minitest.respond_to?(:keep_scheduler) and Minitest.keep_scheduler rescue nil)
|
46
|
+
Furnish.shutdown
|
47
|
+
@tempfiles.each do |file|
|
48
|
+
file.unlink
|
49
|
+
end
|
45
50
|
end
|
46
51
|
end
|
47
52
|
end
|
@@ -56,14 +61,17 @@ module Furnish
|
|
56
61
|
#
|
57
62
|
# RunningSchedulerTestCase deals with managing a running scheduler for you.
|
58
63
|
#
|
59
|
-
class
|
64
|
+
class SchedulerTest < Test
|
60
65
|
##
|
61
66
|
# Furnish::Scheduler object.
|
62
67
|
attr_reader :sched
|
63
68
|
|
64
69
|
def setup # :nodoc:
|
65
70
|
super
|
66
|
-
|
71
|
+
if $sched
|
72
|
+
@sched = $sched
|
73
|
+
end
|
74
|
+
@sched ||= Furnish::Scheduler.new
|
67
75
|
@monitor = Thread.new { loop { @sched.running?; sleep 1 } }
|
68
76
|
@monitor.abort_on_exception = true
|
69
77
|
end
|
@@ -95,7 +103,7 @@ module Furnish
|
|
95
103
|
# Inherits from SchedulerTestCase and manages a running scheduler in
|
96
104
|
# conjunction with all the other features.
|
97
105
|
#
|
98
|
-
class
|
106
|
+
class RunningSchedulerTest < SchedulerTest
|
99
107
|
def setup # :nodoc:
|
100
108
|
super
|
101
109
|
@sched.run
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Monkey Patches for Minitest for Furnish::Test
|
3
|
+
#
|
4
|
+
module Minitest
|
5
|
+
class << self
|
6
|
+
#
|
7
|
+
# If this is set, the scheduler will be kept running between test methods,
|
8
|
+
# so that it can be re-used. This can be used to save some time in
|
9
|
+
# situaitons where a long-running provision will be used in all methods in
|
10
|
+
# a suite.
|
11
|
+
#
|
12
|
+
attr_accessor :keep_scheduler
|
13
|
+
|
14
|
+
remove_method :__run
|
15
|
+
|
16
|
+
def __run(reporter, options) # :nodoc:
|
17
|
+
at_exit do
|
18
|
+
if Furnish.initialized?
|
19
|
+
$sched.force_deprovision = true
|
20
|
+
#$sched.teardown
|
21
|
+
#Furnish.shutdown
|
22
|
+
FileUtils.rm_f('test.db')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Minitest::Runnable.runnables.each do |suite|
|
27
|
+
begin
|
28
|
+
if keep_scheduler
|
29
|
+
require 'fileutils'
|
30
|
+
Furnish.init('test.db') unless Furnish.initialized?
|
31
|
+
|
32
|
+
if ENV["FURNISH_DEBUG"]
|
33
|
+
Furnish.logger = Furnish::Logger.new($stderr, 3)
|
34
|
+
end
|
35
|
+
|
36
|
+
$sched ||= Furnish::Scheduler.new
|
37
|
+
$sched.run
|
38
|
+
end
|
39
|
+
|
40
|
+
if suite.respond_to?(:before_suite)
|
41
|
+
suite.before_suite
|
42
|
+
end
|
43
|
+
|
44
|
+
suite.run(reporter, options)
|
45
|
+
ensure
|
46
|
+
if suite.respond_to?(:after_suite)
|
47
|
+
suite.after_suite
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/furnish/version.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/mt_cases.rb
CHANGED
@@ -3,7 +3,7 @@ require 'furnish/test'
|
|
3
3
|
|
4
4
|
module Furnish
|
5
5
|
# These tests are run for both threaded and serial cases.
|
6
|
-
class
|
6
|
+
class RestartingSchedulerTest < SchedulerTest
|
7
7
|
def teardown
|
8
8
|
sched.stop
|
9
9
|
super
|
@@ -361,6 +361,27 @@ module Furnish
|
|
361
361
|
sched.force_deprovision = true
|
362
362
|
sched.teardown
|
363
363
|
refute_includes(sched.vm.solved, "blarg")
|
364
|
+
|
365
|
+
dummy = StartFailDummy.new
|
366
|
+
assert(sched.schedule_provision('blarg', StartFailDummy.new))
|
367
|
+
|
368
|
+
assert_raises(RuntimeError) do
|
369
|
+
sched.run
|
370
|
+
|
371
|
+
unless sched.serial
|
372
|
+
sched.wait_for('blarg')
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
sched.force_deprovision = false
|
377
|
+
refute_includes(sched.vm.solved, "blarg")
|
378
|
+
unless sched.serial
|
379
|
+
assert_raises(RuntimeError) do
|
380
|
+
sched.down("blarg")
|
381
|
+
end
|
382
|
+
end
|
383
|
+
sched.force_deprovision = true
|
384
|
+
sched.down("blarg")
|
364
385
|
end
|
365
386
|
end
|
366
387
|
end
|
data/test/test_api.rb
CHANGED
data/test/test_dummy.rb
CHANGED
data/test/test_logger.rb
CHANGED
data/test/test_protocol.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
class TestProtocol < Furnish::
|
3
|
+
class TestProtocol < Furnish::Test
|
4
4
|
#--
|
5
5
|
# see the Furnish::Protocol docs for truth tables and whatnot
|
6
6
|
#++
|
@@ -209,5 +209,13 @@ class TestProtocol < Furnish::TestCase
|
|
209
209
|
proto2.accepts(:bar, "bar", Integer)
|
210
210
|
|
211
211
|
refute(proto2.accepts_from(proto1), "nothing accepted is yielded")
|
212
|
+
|
213
|
+
proto1 = Furnish::Protocol.new
|
214
|
+
proto2 = Furnish::Protocol.new
|
215
|
+
proto1.yields(:foo, "foo", String)
|
216
|
+
proto1.accepts(:bar, "bar", String)
|
217
|
+
proto1.accepts(:foo, "foo", String)
|
218
|
+
|
219
|
+
assert(proto2.accepts_from(proto1), "only one of the types is matched")
|
212
220
|
end
|
213
221
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'dummy_classes'
|
3
|
+
require 'furnish/provisioners/dummy_vm'
|
2
4
|
|
3
5
|
# NOTE the dummy classes in this file are defined in test/dummy_classes.rb
|
4
|
-
class TestProvisionerGroup < Furnish::
|
6
|
+
class TestProvisionerGroup < Furnish::Test
|
5
7
|
def test_constructor
|
6
8
|
dummy = Dummy.new
|
7
9
|
pg = Furnish::ProvisionerGroup.new(dummy, 'blarg')
|
@@ -206,4 +208,28 @@ class TestProvisionerGroup < Furnish::TestCase
|
|
206
208
|
assert(pg.last.run_state[:shutdown])
|
207
209
|
end
|
208
210
|
end
|
211
|
+
|
212
|
+
def test_vms
|
213
|
+
vm1 = Furnish::Provisioner::DummyVM.new
|
214
|
+
vm2 = Furnish::Provisioner::DummyVM.new
|
215
|
+
|
216
|
+
pg1 = Furnish::ProvisionerGroup.new([vm1], 'test1')
|
217
|
+
pg2 = Furnish::ProvisionerGroup.new([vm2], 'test2')
|
218
|
+
|
219
|
+
pg1.first.add_vm('test', {})
|
220
|
+
pg2.first.add_vm('test2', {})
|
221
|
+
|
222
|
+
assert_equal({ pg1.first => ['test'] }, pg1.vms)
|
223
|
+
assert_equal({ pg2.first => ['test2'] }, pg2.vms)
|
224
|
+
|
225
|
+
vm1 = Furnish::Provisioner::DummyVM.new
|
226
|
+
dummy = Dummy.new
|
227
|
+
vm2 = Furnish::Provisioner::DummyVM.new
|
228
|
+
|
229
|
+
pg1 = Furnish::ProvisionerGroup.new([vm1, dummy, vm2], 'test1')
|
230
|
+
pg1.first.add_vm('test', { })
|
231
|
+
pg1.last.add_vm('test2', { })
|
232
|
+
|
233
|
+
assert_equal({ pg1.first => ['test', 'test2'], pg1.last => ['test', 'test2'] }, pg1.vms)
|
234
|
+
end
|
209
235
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'furnish/provisioners/dummy_vm'
|
3
|
+
|
4
|
+
DummyVM = Furnish::Provisioner::DummyVM
|
5
|
+
|
6
|
+
class TestProvisionerVM < Furnish::Test
|
7
|
+
def test_definition
|
8
|
+
assert_kind_of(Furnish::Provisioner::API, DummyVM.new)
|
9
|
+
assert_kind_of(Furnish::Provisioner::VM, DummyVM.new)
|
10
|
+
assert_respond_to(DummyVM.new, :vm)
|
11
|
+
assert_equal([], DummyVM.new.list_vms)
|
12
|
+
assert_raises(RuntimeError) { DummyVM.new.add_vm("foo", 1) }
|
13
|
+
assert_raises(RuntimeError) { DummyVM.new.remove_vm("foo") }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_group
|
17
|
+
dummy = DummyVM.new
|
18
|
+
assert_nil(dummy.vm)
|
19
|
+
group = Furnish::ProvisionerGroup.new([dummy], 'test1')
|
20
|
+
|
21
|
+
assert_kind_of(Palsy::Map, group.first.vm)
|
22
|
+
group
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_api
|
26
|
+
group = test_group
|
27
|
+
group.first.add_vm("foo", "one" => "two", "three" => "four")
|
28
|
+
assert_raises(ArgumentError) { group.first.add_vm("foo", 1) }
|
29
|
+
assert_includes(group.first.list_vms, "foo")
|
30
|
+
group.first.remove_vm("foo")
|
31
|
+
refute_includes(group.first.list_vms, "foo")
|
32
|
+
end
|
33
|
+
end
|
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'dummy_classes'
|
3
|
+
|
4
|
+
class TestSchedulerBasic < Furnish::SchedulerTest
|
5
|
+
def test_initialized
|
6
|
+
Furnish::Scheduler.new # should not raise
|
7
|
+
Furnish.instance_variable_set(:@initialized, false)
|
8
|
+
assert_raises(RuntimeError) { Furnish::Scheduler.new }
|
9
|
+
end
|
2
10
|
|
3
|
-
class TestSchedulerBasic < Furnish::SchedulerTestCase
|
4
11
|
def test_schedule_provision
|
5
12
|
assert(sched.schedule_provision('blarg', [Dummy.new]), 'we can schedule')
|
6
13
|
assert_includes(sched.vm.waiters.keys, 'blarg', 'exists in the waiters')
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'mt_cases'
|
2
3
|
|
3
4
|
# NOTE the dummy classes in this file are defined in test/dummy_classes.rb
|
4
|
-
class TestSchedulerThreaded < Furnish::
|
5
|
+
class TestSchedulerThreaded < Furnish::RestartingSchedulerTest
|
5
6
|
def setup
|
6
7
|
super
|
7
8
|
sched.serial = false
|
data/test/test_vm.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: furnish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik Hollensbe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: palsy
|
@@ -28,30 +28,30 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '5.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '5.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: guard-minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,8 +144,12 @@ files:
|
|
144
144
|
- lib/furnish/provisioner_group.rb
|
145
145
|
- lib/furnish/provisioners/api.rb
|
146
146
|
- lib/furnish/provisioners/dummy.rb
|
147
|
+
- lib/furnish/provisioners/dummy_include.rb
|
148
|
+
- lib/furnish/provisioners/dummy_vm.rb
|
149
|
+
- lib/furnish/provisioners/vm.rb
|
147
150
|
- lib/furnish/scheduler.rb
|
148
151
|
- lib/furnish/test.rb
|
152
|
+
- lib/furnish/test/scheduler_runner.rb
|
149
153
|
- lib/furnish/version.rb
|
150
154
|
- lib/furnish/vm.rb
|
151
155
|
- test/dummy_classes.rb
|
@@ -156,6 +160,7 @@ files:
|
|
156
160
|
- test/test_logger.rb
|
157
161
|
- test/test_protocol.rb
|
158
162
|
- test/test_provisioner_group.rb
|
163
|
+
- test/test_provisioner_vm.rb
|
159
164
|
- test/test_scheduler_basic.rb
|
160
165
|
- test/test_scheduler_serial.rb
|
161
166
|
- test/test_scheduler_threaded.rb
|
@@ -192,6 +197,7 @@ test_files:
|
|
192
197
|
- test/test_logger.rb
|
193
198
|
- test/test_protocol.rb
|
194
199
|
- test/test_provisioner_group.rb
|
200
|
+
- test/test_provisioner_vm.rb
|
195
201
|
- test/test_scheduler_basic.rb
|
196
202
|
- test/test_scheduler_serial.rb
|
197
203
|
- test/test_scheduler_threaded.rb
|