automateit 0.70923
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.
- data.tar.gz.sig +1 -0
- data/CHANGES.txt +100 -0
- data/Hoe.rake +35 -0
- data/Manifest.txt +111 -0
- data/README.txt +44 -0
- data/Rakefile +284 -0
- data/TESTING.txt +57 -0
- data/TODO.txt +26 -0
- data/TUTORIAL.txt +390 -0
- data/bin/ai +3 -0
- data/bin/aifield +82 -0
- data/bin/aitag +128 -0
- data/bin/automateit +117 -0
- data/docs/friendly_errors.txt +50 -0
- data/docs/previews.txt +86 -0
- data/env.sh +4 -0
- data/examples/basic/Rakefile +26 -0
- data/examples/basic/config/automateit_env.rb +16 -0
- data/examples/basic/config/fields.yml +3 -0
- data/examples/basic/config/tags.yml +13 -0
- data/examples/basic/dist/README.txt +9 -0
- data/examples/basic/dist/myapp_server.erb +30 -0
- data/examples/basic/install.log +15 -0
- data/examples/basic/lib/README.txt +10 -0
- data/examples/basic/recipes/README.txt +4 -0
- data/examples/basic/recipes/install.rb +53 -0
- data/examples/basic/recipes/uninstall.rb +6 -0
- data/gpl.txt +674 -0
- data/lib/automateit.rb +66 -0
- data/lib/automateit/account_manager.rb +106 -0
- data/lib/automateit/account_manager/linux.rb +171 -0
- data/lib/automateit/account_manager/passwd.rb +69 -0
- data/lib/automateit/account_manager/portable.rb +136 -0
- data/lib/automateit/address_manager.rb +165 -0
- data/lib/automateit/address_manager/linux.rb +80 -0
- data/lib/automateit/address_manager/portable.rb +37 -0
- data/lib/automateit/cli.rb +80 -0
- data/lib/automateit/common.rb +65 -0
- data/lib/automateit/constants.rb +33 -0
- data/lib/automateit/edit_manager.rb +292 -0
- data/lib/automateit/error.rb +10 -0
- data/lib/automateit/field_manager.rb +103 -0
- data/lib/automateit/interpreter.rb +641 -0
- data/lib/automateit/package_manager.rb +242 -0
- data/lib/automateit/package_manager/apt.rb +63 -0
- data/lib/automateit/package_manager/egg.rb +64 -0
- data/lib/automateit/package_manager/gem.rb +179 -0
- data/lib/automateit/package_manager/portage.rb +69 -0
- data/lib/automateit/package_manager/yum.rb +65 -0
- data/lib/automateit/platform_manager.rb +47 -0
- data/lib/automateit/platform_manager/darwin.rb +30 -0
- data/lib/automateit/platform_manager/debian.rb +26 -0
- data/lib/automateit/platform_manager/freebsd.rb +25 -0
- data/lib/automateit/platform_manager/gentoo.rb +26 -0
- data/lib/automateit/platform_manager/lsb.rb +40 -0
- data/lib/automateit/platform_manager/struct.rb +78 -0
- data/lib/automateit/platform_manager/uname.rb +29 -0
- data/lib/automateit/platform_manager/windows.rb +33 -0
- data/lib/automateit/plugin.rb +7 -0
- data/lib/automateit/plugin/base.rb +32 -0
- data/lib/automateit/plugin/driver.rb +218 -0
- data/lib/automateit/plugin/manager.rb +232 -0
- data/lib/automateit/project.rb +460 -0
- data/lib/automateit/root.rb +14 -0
- data/lib/automateit/service_manager.rb +79 -0
- data/lib/automateit/service_manager/chkconfig.rb +39 -0
- data/lib/automateit/service_manager/rc_update.rb +37 -0
- data/lib/automateit/service_manager/sysv.rb +126 -0
- data/lib/automateit/service_manager/update_rcd.rb +35 -0
- data/lib/automateit/shell_manager.rb +261 -0
- data/lib/automateit/shell_manager/base_link.rb +67 -0
- data/lib/automateit/shell_manager/link.rb +24 -0
- data/lib/automateit/shell_manager/portable.rb +421 -0
- data/lib/automateit/shell_manager/symlink.rb +32 -0
- data/lib/automateit/shell_manager/which.rb +25 -0
- data/lib/automateit/tag_manager.rb +63 -0
- data/lib/automateit/tag_manager/struct.rb +101 -0
- data/lib/automateit/tag_manager/tag_parser.rb +91 -0
- data/lib/automateit/tag_manager/yaml.rb +29 -0
- data/lib/automateit/template_manager.rb +55 -0
- data/lib/automateit/template_manager/base.rb +172 -0
- data/lib/automateit/template_manager/erb.rb +17 -0
- data/lib/ext/metaclass.rb +17 -0
- data/lib/ext/object.rb +18 -0
- data/lib/hashcache.rb +22 -0
- data/lib/helpful_erb.rb +63 -0
- data/lib/nested_error.rb +33 -0
- data/lib/queued_logger.rb +68 -0
- data/lib/tempster.rb +239 -0
- data/misc/index_gem_repository.rb +303 -0
- data/misc/setup_egg.rb +12 -0
- data/misc/setup_gem_dependencies.sh +7 -0
- data/misc/setup_rubygems.sh +21 -0
- data/misc/which.cmd +6 -0
- data/spec/extras/automateit_service_sysv_test +50 -0
- data/spec/extras/scratch.rb +15 -0
- data/spec/extras/simple_recipe.rb +8 -0
- data/spec/integration/account_manager_spec.rb +218 -0
- data/spec/integration/address_manager_linux_spec.rb +119 -0
- data/spec/integration/address_manager_portable_spec.rb +30 -0
- data/spec/integration/cli_spec.rb +215 -0
- data/spec/integration/examples_spec.rb +54 -0
- data/spec/integration/examples_spec_editor.rb +71 -0
- data/spec/integration/package_manager_spec.rb +104 -0
- data/spec/integration/platform_manager_spec.rb +69 -0
- data/spec/integration/service_manager_sysv_spec.rb +115 -0
- data/spec/integration/shell_manager_spec.rb +471 -0
- data/spec/integration/template_manager_erb_spec.rb +31 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/unit/edit_manager_spec.rb +162 -0
- data/spec/unit/field_manager_spec.rb +79 -0
- data/spec/unit/hashcache_spec.rb +28 -0
- data/spec/unit/interpreter_spec.rb +98 -0
- data/spec/unit/platform_manager_spec.rb +44 -0
- data/spec/unit/plugins_spec.rb +253 -0
- data/spec/unit/tag_manager_spec.rb +189 -0
- data/spec/unit/template_manager_erb_spec.rb +137 -0
- metadata +249 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "/../spec_helper.rb")
|
|
2
|
+
|
|
3
|
+
#===[ stub classes ]====================================================# {{{
|
|
4
|
+
|
|
5
|
+
class MyManager < AutomateIt::Plugin::Manager
|
|
6
|
+
alias_methods :mymethod
|
|
7
|
+
|
|
8
|
+
def mymethod(opts)
|
|
9
|
+
dispatch(opts)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class MyManager::BaseDriver < AutomateIt::Plugin::Driver
|
|
14
|
+
# Is abstract by default
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class MyManager::AnotherBaseDriver < MyManager::BaseDriver
|
|
18
|
+
abstract_driver
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class MyManager::MyUnsuitableDriver < MyManager::BaseDriver
|
|
22
|
+
# +suitability+ method deliberately not implemented to test errors
|
|
23
|
+
|
|
24
|
+
depends_on \
|
|
25
|
+
:files => ["non_existent_file"],
|
|
26
|
+
:directories => ["non_existent_directory"],
|
|
27
|
+
:programs => ["non_existent_program"]
|
|
28
|
+
|
|
29
|
+
def unavailable_method
|
|
30
|
+
_raise_unless_available
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class MyManager::MyUnimplementedDriver < MyManager::BaseDriver
|
|
35
|
+
def available?
|
|
36
|
+
true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def suitability(method, *args)
|
|
40
|
+
return 50
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# +mymethod+ method deliberately not implemented to test errors
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class MyManager::MyFirstDriver < MyManager::BaseDriver
|
|
48
|
+
depends_on :directories => ["/"]
|
|
49
|
+
|
|
50
|
+
def suitability(method, *args)
|
|
51
|
+
case method
|
|
52
|
+
when :mymethod
|
|
53
|
+
return args.first[:one] == 1 ? 10 : 0
|
|
54
|
+
else
|
|
55
|
+
return -1
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def mymethod(opts)
|
|
60
|
+
opts[:one]
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class MyManager::MySecondDriver < MyManager::BaseDriver
|
|
65
|
+
def available?
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def suitability(method, *args)
|
|
70
|
+
case method
|
|
71
|
+
when :mymethod
|
|
72
|
+
return args.first[:one] == 1 ? 5 : 0
|
|
73
|
+
else
|
|
74
|
+
return -1
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def mymethod(opts)
|
|
79
|
+
opts[:one]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class MyManagerSubclass < AutomateIt::Plugin::Manager
|
|
84
|
+
abstract_manager
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class MyManagerSubclassImplementation < MyManagerSubclass
|
|
88
|
+
end
|
|
89
|
+
# }}}
|
|
90
|
+
#===[ rspec ]===========================================================
|
|
91
|
+
|
|
92
|
+
describe "AutomateIt::Plugin::Manager" do
|
|
93
|
+
before(:all) do
|
|
94
|
+
@x = AutomateIt::Plugin::Manager
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should have plugins" do
|
|
98
|
+
@x.classes.should include(MyManager)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should not have abstract plugins" do
|
|
102
|
+
@x.classes.should_not include(MyManagerSubclass)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should have implementations of abstract plugins" do
|
|
106
|
+
@x.classes.should include(MyManagerSubclassImplementation)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe "MyManager" do
|
|
111
|
+
before(:all) do
|
|
112
|
+
@m = MyManager.new
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should have drivers" do
|
|
116
|
+
for driver in [MyManager::MyUnsuitableDriver, MyManager::MyFirstDriver, MyManager::MySecondDriver]
|
|
117
|
+
@m.class.driver_classes.should include(driver)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should inherit common instance mehtods" do
|
|
122
|
+
@m.should respond_to(:log)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should access drivers by index keys" do
|
|
126
|
+
@m[:my_first_driver].should be_a_kind_of(MyManager::MyFirstDriver)
|
|
127
|
+
@m.drivers[:my_first_driver].should be_a_kind_of(MyManager::MyFirstDriver)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "should have aliased methods" do
|
|
131
|
+
@m.class.aliased_methods.should include(:mymethod)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should respond to aliased methods" do
|
|
135
|
+
@m.should respond_to(:mymethod)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should have an interpreter instance" do
|
|
139
|
+
@m.interpreter.should be_a_kind_of(AutomateIt::Interpreter)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# XXX Plugins spec -- Instantiating a Plugin outside of an Interpreter should retain consistent object references
|
|
143
|
+
# it "should inject interpreter instance into drivers" do
|
|
144
|
+
# @m.interpreter.object_id.should == m[:my_first_driver].interpreter.object_id
|
|
145
|
+
# end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
describe "MyManager's drivers" do
|
|
149
|
+
before(:all) do
|
|
150
|
+
@m = MyManager.new
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should be available" do
|
|
154
|
+
MyManager::MyFirstDriver.new.available?.should be_true
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should fail on unavailable methods" do
|
|
158
|
+
lambda{ MyManager::MyUnsuitableDriver.new.unavailable_method }.should
|
|
159
|
+
raise_error(NotImplementedError, /non_existent/)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "should have a token" do
|
|
163
|
+
MyManager::MyFirstDriver.token.should == :my_first_driver
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "should consider good drivers to be suitable" do
|
|
167
|
+
MyManager::MyFirstDriver.new.suitability(:mymethod, :one => 1).should > 0
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "should not consider drivers that don't declare their suitability" do
|
|
171
|
+
MyManager::MyUnsuitableDriver.new.suitability(:mymethod, :one => 1).should < 0
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "should determine suitability levels" do
|
|
175
|
+
rs = @m.driver_suitability_levels_for(:mymethod, :one => 1)
|
|
176
|
+
rs[:my_first_driver].should == 10
|
|
177
|
+
rs[:my_second_driver].should == 5
|
|
178
|
+
rs[:my_unsuitable_driver].should be_nil
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should choose suitable driver" do
|
|
182
|
+
@m.driver_for(:mymethod, :one => 1).should be_a_kind_of(MyManager::MyFirstDriver)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "should not choose driver if none match" do
|
|
186
|
+
lambda { @m.driver_for(:mymethod, :one => 9) }.should raise_error(NotImplementedError)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "should dispatch_to suitable driver" do
|
|
190
|
+
@m.dispatch_to(:mymethod, :one => 1).should == 1
|
|
191
|
+
@m.mymethod(:one => 1).should == 1
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should fail dispatch_to if no suitable driver is found" do
|
|
195
|
+
lambda { @m.dispatch_to(:mymethod, :one => 9) }.should raise_error(NotImplementedError)
|
|
196
|
+
lambda { @m.mymethod(:one => 9) }.should raise_error(NotImplementedError)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "should dispatch_to to default driver regardless of suitability" do
|
|
200
|
+
@m.default(:my_unimplemented_driver)
|
|
201
|
+
lambda { @m.dispatch_to(:mymethod, :one => 1) }.should raise_error(NoMethodError)
|
|
202
|
+
lambda { @m.mymethod(:one => 1) }.should raise_error(NoMethodError)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "should have an interpreter instance" do
|
|
206
|
+
MyManager::MyFirstDriver.new.interpreter.should be_a_kind_of(AutomateIt::Interpreter)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "should share object instances" do
|
|
210
|
+
@m[:my_first_driver].should == @m.interpreter.my_manager[:my_first_driver]
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe AutomateIt::Interpreter do
|
|
215
|
+
before(:all) do
|
|
216
|
+
@a = AutomateIt::Interpreter.new
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it "should instantiate plugins" do
|
|
220
|
+
@a.should respond_to(:plugins)
|
|
221
|
+
@a.plugins.should include(:my_manager)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should expose plugin instance aliases" do
|
|
225
|
+
@a.should respond_to(:my_manager)
|
|
226
|
+
@a.my_manager.class.should == MyManager
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it "should expose plugin method aliases" do
|
|
230
|
+
@a.should respond_to(:mymethod)
|
|
231
|
+
lambda {@a.mymethod(:one => 1)}.should_not raise_error
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it "should inject itself into plugins" do
|
|
235
|
+
@a.my_manager.interpreter.should == @a
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should inject itself into drivers" do
|
|
239
|
+
@a.my_manager[:my_first_driver].interpreter.should == @a
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should not see abstract managers" do
|
|
243
|
+
@a.plugins.should_not include(MyManagerSubclass.token)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "should not see abstract drivers" do
|
|
247
|
+
@a.my_manager.drivers.should_not include(MyManager::AnotherBaseDriver.token)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "should not see base drivers" do
|
|
251
|
+
@a.my_manager.drivers.should_not include(MyManager::BaseDriver.token)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "/../spec_helper.rb")
|
|
2
|
+
|
|
3
|
+
describe "AutomateIt::TagManager", :shared => true do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@a = AutomateIt.new
|
|
6
|
+
@a.address_manager.should_receive(:hostnames).any_number_of_times.and_return(["kurou", "kurou.foo"])
|
|
7
|
+
@a.platform_manager.setup(
|
|
8
|
+
:default => :struct,
|
|
9
|
+
:struct => {
|
|
10
|
+
:os => "mizrahi",
|
|
11
|
+
:arch => "realian",
|
|
12
|
+
:distro => "momo",
|
|
13
|
+
:version => "s100",
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
@m = @a.tag_manager
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should have tags" do
|
|
20
|
+
@a.tags.should be_a_kind_of(Enumerable)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should have tags that include tag for hostname" do
|
|
24
|
+
@a.tags.should include("kurou")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should have tag for short hostname" do
|
|
28
|
+
@a.tagged?("kurou").should be_true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should have tag for long hostname" do
|
|
32
|
+
@a.tagged?("kurou.foo").should be_true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should have tag for OS" do
|
|
36
|
+
@a.tagged?("mizrahi").should be_true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should have tag for OS/arch" do
|
|
40
|
+
@a.tagged?("mizrahi_realian").should be_true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should have tag for distro/release" do
|
|
44
|
+
@a.tagged?("momo_s100").should be_true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should have tag for a role" do
|
|
48
|
+
@a.tagged?("apache_servers").should be_true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should match a symbol query" do
|
|
52
|
+
@a.tagged?(:apache_servers).should be_true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should match a string query" do
|
|
56
|
+
@a.tagged?("apache_servers").should be_true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should not match unknown symbol keys" do
|
|
60
|
+
@a.tagged?(:foo).should be_false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should not match unknown string keys" do
|
|
64
|
+
@a.tagged?("foo").should be_false
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should match an AND query" do
|
|
68
|
+
@a.tagged?("kurou && apache_servers").should be_true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should match an OR query" do
|
|
72
|
+
@a.tagged?("kurou || apache_servers").should be_true
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should match a grouped AND and OR query" do
|
|
76
|
+
@a.tagged?("(kurou || apache_servers) && momo_s100").should be_true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should not match AND with unknown keys" do
|
|
80
|
+
@a.tagged?("kurou && foo").should be_false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should not match OR with unknown keys" do
|
|
84
|
+
@a.tagged?("foo && bar").should be_false
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should query tags for a specific host" do
|
|
88
|
+
@a.tagged?("proxy_servers", "kurou").should be_false
|
|
89
|
+
@a.tagged?("proxy_servers", "akane.foo").should be_true
|
|
90
|
+
@a.tagged?("proxy_servers", "akane").should be_true
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should append tags" do
|
|
94
|
+
@a.tagged?("magic").should be_false
|
|
95
|
+
@a.tags << "magic"
|
|
96
|
+
@a.tagged?("magic").should be_true
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should find tags for a host using an array" do
|
|
100
|
+
@a.tags_for(["kurou"]).should include("apache_servers")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should find tags for a host using a string" do
|
|
104
|
+
@a.tags_for("akane.foo.bar").should include("proxy_servers")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should find hosts with a tag" do
|
|
108
|
+
hosts = @a.hosts_tagged_with("apache_servers")
|
|
109
|
+
hosts.should include("kurou")
|
|
110
|
+
hosts.should include("shirou")
|
|
111
|
+
hosts.should_not include("akane")
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should find using negative queries" do
|
|
115
|
+
@a.tagged?("akane").should be_false
|
|
116
|
+
@a.tagged?("!akane").should be_true
|
|
117
|
+
@a.tagged?("!akane && !proxy_servers").should be_true
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should include group aliases" do
|
|
121
|
+
@a.hosts_tagged_with("all_servers").sort.should == ["kurou", "shirou", "akane.foo"].sort
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should exclude hosts from groups" do
|
|
125
|
+
@a.hosts_tagged_with("apache_servers_except_kurou").should == ["shirou"]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should exclude groups from groups" do
|
|
129
|
+
@a.hosts_tagged_with("all_servers_except_proxy_servers").sort.should == ["kurou", "shirou"].sort
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe "AutomateIt::TagManager::Struct" do
|
|
134
|
+
it_should_behave_like "AutomateIt::TagManager"
|
|
135
|
+
|
|
136
|
+
before(:all) do
|
|
137
|
+
@m.setup(
|
|
138
|
+
:default => :struct,
|
|
139
|
+
:struct => {
|
|
140
|
+
"apache_servers" => [
|
|
141
|
+
"kurou",
|
|
142
|
+
"shirou",
|
|
143
|
+
],
|
|
144
|
+
"proxy_servers" => [
|
|
145
|
+
"akane.foo",
|
|
146
|
+
],
|
|
147
|
+
"all_servers" => [
|
|
148
|
+
"@apache_servers",
|
|
149
|
+
"@proxy_servers",
|
|
150
|
+
],
|
|
151
|
+
"apache_servers_except_kurou" => [
|
|
152
|
+
"@apache_servers",
|
|
153
|
+
"!kurou",
|
|
154
|
+
],
|
|
155
|
+
"all_servers_except_proxy_servers" => [
|
|
156
|
+
"@all_servers",
|
|
157
|
+
"!@proxy_servers",
|
|
158
|
+
],
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
describe "AutomateIt::TagManager::YAML" do
|
|
165
|
+
it_should_behave_like "AutomateIt::TagManager"
|
|
166
|
+
|
|
167
|
+
before(:all) do
|
|
168
|
+
@m[:yaml].should_receive(:_read).with("demo.yml").and_return(<<-EOB)
|
|
169
|
+
<%="apache_servers"%>:
|
|
170
|
+
- kurou
|
|
171
|
+
- shirou
|
|
172
|
+
proxy_servers:
|
|
173
|
+
- akane.foo
|
|
174
|
+
all_servers:
|
|
175
|
+
- @apache_servers
|
|
176
|
+
- @proxy_servers
|
|
177
|
+
apache_servers_except_kurou:
|
|
178
|
+
- @apache_servers
|
|
179
|
+
- !kurou
|
|
180
|
+
all_servers_except_proxy_servers:
|
|
181
|
+
- @all_servers
|
|
182
|
+
- !@proxy_servers
|
|
183
|
+
EOB
|
|
184
|
+
@m.setup(
|
|
185
|
+
:default => :yaml,
|
|
186
|
+
:file => "demo.yml"
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "/../spec_helper.rb")
|
|
2
|
+
|
|
3
|
+
describe "AutomateIt::TemplateManager::ERB" do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@a = AutomateIt.new(:verbosity => Logger::WARN)
|
|
6
|
+
@m = @a.template_manager
|
|
7
|
+
@d = @m[:erb]
|
|
8
|
+
|
|
9
|
+
@source = "source_for_template"
|
|
10
|
+
@target = "target_for_template"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after(:each) do
|
|
14
|
+
if File.exists?(@target)
|
|
15
|
+
File.unlink(@target)
|
|
16
|
+
raise "A write wasn't intercepted by the mocks! Removing file and giving up."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should render a string template" do
|
|
21
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(false)
|
|
22
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
23
|
+
|
|
24
|
+
@a.render(:text => "my template content", :to => @target).should be_true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should render a file template" do
|
|
28
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
29
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(false)
|
|
30
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
31
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
32
|
+
|
|
33
|
+
@a.render(@source, @target).should be_true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should render with local variables" do
|
|
37
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
38
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(false)
|
|
39
|
+
@d.should_receive(:_read).once.with(@source).and_return("hello <%=entity%>")
|
|
40
|
+
@d.should_receive(:_write).once.with(@target, "hello world").and_return(true)
|
|
41
|
+
|
|
42
|
+
@a.render(@source, @target, :locals => {:entity => "world"}).should be_true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should render when the template was updated" do
|
|
46
|
+
timestamp = Time.now
|
|
47
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
48
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
49
|
+
@d.should_receive(:_read).once.with(@target).and_return("my old content")
|
|
50
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
51
|
+
@d.should_receive(:_mtime).once.with(@source).and_return(timestamp+1)
|
|
52
|
+
@d.should_receive(:_mtime).once.with(@target).and_return(timestamp)
|
|
53
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
54
|
+
|
|
55
|
+
@a.render(@source, @target, :check => :timestamp).should be_true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "shouldn't render when the template wasn't updated" do
|
|
59
|
+
timestamp = Time.now
|
|
60
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
61
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
62
|
+
@d.should_receive(:_mtime).once.with(@source).and_return(timestamp)
|
|
63
|
+
@d.should_receive(:_mtime).once.with(@target).and_return(timestamp+1)
|
|
64
|
+
|
|
65
|
+
@a.render(@source, @target, :check => :timestamp).should be_false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should render when the template's dependencies are updated" do
|
|
69
|
+
timestamp = Time.now
|
|
70
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
71
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
72
|
+
@d.should_receive(:_read).once.with(@target).and_return("my old content")
|
|
73
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
74
|
+
@d.should_receive(:_mtime).once.with("foo").and_return(timestamp+1)
|
|
75
|
+
@d.should_receive(:_mtime).once.with(@source).and_return(timestamp)
|
|
76
|
+
@d.should_receive(:_mtime).once.with(@target).and_return(timestamp)
|
|
77
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
78
|
+
|
|
79
|
+
@a.render(@source, @target, :check => :timestamp, :dependencies => ["foo"]).should be_true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "shouldn't render when the template's dependencies weren't updated" do
|
|
83
|
+
timestamp = Time.now
|
|
84
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
85
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
86
|
+
@d.should_receive(:_mtime).once.with("foo").and_return(timestamp)
|
|
87
|
+
@d.should_receive(:_mtime).once.with(@source).and_return(timestamp)
|
|
88
|
+
@d.should_receive(:_mtime).once.with(@target).and_return(timestamp+1)
|
|
89
|
+
|
|
90
|
+
@a.render(@source, @target, :check => :timestamp, :dependencies => ["foo"]).should be_false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should render when forced even if the template wasn't updated" do
|
|
94
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
95
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
96
|
+
@d.should_receive(:_read).once.with(@target).and_return("my old content")
|
|
97
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
98
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
99
|
+
|
|
100
|
+
@a.render(@source, @target, :check => :timestamp, :dependencies => ["foo"], :force => true).should be_true
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should render if told to check the existence of output and it doesn't exist" do
|
|
104
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
105
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(false)
|
|
106
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
107
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
108
|
+
|
|
109
|
+
@a.render(@source, @target, :check => :exists).should be_true
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "shouldn't render if told to check the existence of output and it exists" do
|
|
113
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
114
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
115
|
+
|
|
116
|
+
@a.render(@source, @target, :check => :exists).should be_false
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should render if told to compare if the output is different" do
|
|
120
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
121
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
122
|
+
@d.should_receive(:_read).once.with(@target).and_return("my old content")
|
|
123
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
124
|
+
@d.should_receive(:_write).once.with(@target, "my template content").and_return(true)
|
|
125
|
+
|
|
126
|
+
@a.render(@source, @target, :check => :compare).should be_true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "shouldn't render if told to compare if the output is the same" do
|
|
130
|
+
@d.should_receive(:_exists?).once.with(@source).and_return(true)
|
|
131
|
+
@d.should_receive(:_exists?).once.with(@target).and_return(true)
|
|
132
|
+
@d.should_receive(:_read).once.with(@target).and_return("my template content")
|
|
133
|
+
@d.should_receive(:_read).once.with(@source).and_return("my template content")
|
|
134
|
+
|
|
135
|
+
@a.render(@source, @target, :check => :compare).should be_false
|
|
136
|
+
end
|
|
137
|
+
end
|