-
Notifications
You must be signed in to change notification settings - Fork 44
/
example_test.rb
232 lines (182 loc) · 6.87 KB
/
example_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
require 'minitest/spec'
#
# Cookbook Name:: spec_examples
# Spec:: default
#
# Copyright 2012, Opscode, Inc.
#
describe_recipe 'spec_examples::default' do
# It's often convenient to load these includes in a separate helper along with
# your own helper methods, but here we just include them directly:
include MiniTest::Chef::Assertions
include MiniTest::Chef::Context
include MiniTest::Chef::Resources
describe "files" do
# = Testing that a file exists =
#
# The simplest assertion is that a file exists following the Chef run:
it "creates the config file" do
file("/etc/fstab").must_exist
end
# All of the matchers starting with 'must_' also have a negative 'wont_'.
# So conversely we can also check that a file does not exist:
it "ensures that the foobar file is removed if present" do
file("/etc/foobar").wont_exist
end
# = Testing for behaviour =
#
# Chef has multiple resource types that create files. We use file to test
# all of them.
#
# This is not valid:
#
# cookbook_file(file_path).must_exist
#
# Testing the behaviour - is the file is created with the right content?
# - is preferable to testing how the file gets there. This way if your
# recipe switches from using a cookbook_file resource to a template resource
# your tests should still work.
# Let's go beyond just checking for existence to testing the other file
# attributes.
# = Other file attributes =
# Use .with on a resource and specify the attribute and expected value:
it "has the expected ownership and permissions" do
file("/etc/fstab").must_exist.with(:owner, "root")
end
# You can also use .must_have:
it "only root can modify the config file" do
file("/etc/fstab").must_have(:mode, "644")
end
# And you can chain attributes together if you are asserting several.
# You don't want to get too carried away doing this but it can be useful.
it "only root can modify the config file" do
file("/etc/fstab").must_have(:mode, "644").with(:owner, "root").and(:group, "root")
end
# Alternatively you could express it like this so each assertion is nicely
# self-contained:
describe "only root can modify the config file - alternate syntax" do
let(:config) { file("/etc/fstab") }
it { config.must_have(:mode, "644") }
it { config.must_have(:owner, "root") }
it { config.must_have(:group, "root") }
end
# = Checking file content =
# You can check if a config file contains a string:
it "sets phasers to stun" do
file('/tmp/foo').must_include 'phaser_setting=stun'
end
# Or if a file matches a regular expression:
it "sets phasers to off or stun" do
file('/tmp/foo').must_match /^phaser_setting=(off|stun)$/
file('/tmp/foo').wont_match /^phaser_setting=kill$/
end
# = Checking file timestamps =
it "touches the config to force a reload" do
file("/tmp/foo").must_be_modified_after(run_status.start_time)
end
it "leaves the hosts file alone" do
file("/etc/hosts").wont_be_modified_after(run_status.start_time)
end
# = Directories =
# The file existence and permissions matchers are also valid for
# directories:
it { directory("/etc/").must_exist.with(:owner, "root") }
# = Links =
it "symlinks the foo in" do
link("/tmp/foo-symbolic").must_exist.with(
:link_type, :symbolic).and(:to, "/tmp/foo")
end
end
describe "packages" do
# = Checking for package install =
it "installs my favorite pager" do
package("less").must_be_installed
end
it "doesn't install emacs" do
package("emacs").wont_be_installed
end
# = Package names =
#
# When writing cookbooks intended for use on multiple different operating
# systems or flavors you will often need to supply a different package
# name based on the node.platform.
#
# If you choose to test for package installation in your tests then you
# will also need to provide the right package name, which can lead to
# duplication.
it "installs my favorite pager" do
package(node['spec_examples']['pager']).must_be_installed
end
# = Package versions =
it "installs the package with the right version" do
package("less").must_be_installed.with(:version, "436-1")
end
end
describe "services" do
# You can assert that a service must be running following the converge:
it "runs as a daemon" do
service("chef-client").must_be_running
end
# And that it will start when the server boots:
it "boots on startup" do
service("chef-client").must_be_enabled
end
end
describe "users and groups" do
# = Users =
# Check if a user has been created:
it "creates a user for the daemon to run as" do
user("sshd").must_exist
end
# You can also use .with here to test attributes:
it "creates the user with the expected properties" do
user("sshd").must_exist.with(:home, '/var/run/sshd')
end
it "has an informative comment against the user" do
user("list").must_have(:comment, 'Mailing List Manager')
end
it "has the expected uid" do
user("root").must_have(:uid, 0)
end
# = Groups =
it "creates the users group" do
group("chipmunks").must_exist
end
# Check for group membership, you can pass a single user or an array of
# users:
it "grants group membership to the expected users" do
group("chipmunks").must_include('alvin')
group("chipmunks").must_include(['alvin', 'simon'])
group("chipmunks").wont_include('michelangelo')
end
# Alternatively rather than checking if the group includes specific users
# you can test that the group is made up of exactly the users you specify:
it "grants group membership only to specific users" do
group("chipmunks").must_have(:members, ['alvin', 'simon', 'theodore'])
end
end
describe "cron entries" do
it "creates a crontab entry" do
cron("noop").must_exist.with(:hour, "5").and(:minute, "0").and(:day, "*")
end
it "removes the self-destruct countdown" do
cron("self-destruct").wont_exist
end
end
# Note that the syntax for testing the mount resource is slightly different.
# You need to specify the device in the call to mount.
describe "mount" do
it { mount("/mnt", :device => "/dev/null").must_be_mounted }
it { mount("/mnt", :device => "/dev/null").must_be_enabled.with(:fstype, "tmpfs") }
it { mount("/mnt", :device => "/dev/olympus").wont_be_mounted }
end
describe "networking" do
# = Test network interface settings =
describe "ifconfig" do
it "has the expected network interfaces configured" do
ifconfig(node['ipaddress'], :device => "eth0").must_exist
ifconfig(node['ipaddress'], :device => "eth1").wont_exist
end
end
end
end