furnish 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|