houcho 0.0.3 → 0.0.4
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 +6 -14
- data/README.md +4 -2
- data/bin/houcho +26 -15
- data/houcho.gemspec +3 -0
- data/lib/houcho.rb +14 -3
- data/lib/houcho/cloudforecast.rb +2 -2
- data/lib/houcho/cloudforecast/host.rb +17 -15
- data/lib/houcho/cloudforecast/role.rb +2 -1
- data/lib/houcho/element.rb +2 -2
- data/lib/houcho/host.rb +1 -1
- data/lib/houcho/role.rb +4 -4
- data/lib/houcho/spec/runner.rb +20 -11
- data/lib/houcho/version.rb +1 -1
- data/lib/houcho/yamlhandle.rb +5 -1
- data/spec/houcho_spec.rb +160 -3
- data/spec/spec_helper.rb +3 -0
- data/templates/role/cloudforecast/.gitkeep +0 -0
- metadata +58 -16
- data/lib/houcho/initialize.rb +0 -15
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
YjMwMWI2NGNkMDE0OWRlNDViYjEwNjc2Y2E4MjhkZTc1OGM3NWFmMDVkZWUx
|
10
|
-
NTUwZjRmNjk3MDBkMzg2YjFiN2YxNmJkMGEwYzFhZTUyYWVlYjM1MTVjNjRh
|
11
|
-
ZjFkYjc2N2E2ZTJiNWY3NTQ4YmU3ZmRhZmE0OGU1NTgwMzA5OGY=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
M2IyNTQ4ZmZmYTY4MThlN2YwMzM1MDhhZDMzOThlNTgzNDc3NjJjYmQwZDI5
|
14
|
-
YzNlZTBiZDJhYjJjMzcxNzZhNzFlMWRhYzFlNGNhZmY3NzViMTVmMTE0MjBk
|
15
|
-
MzZhNTYxNTkwN2M5NTg1MDNhM2E4OWNhYjFiYjNjOGNmYjViOWU=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: df80b6d9b4a0a338d66374bb5e501e4d0fa31500
|
4
|
+
data.tar.gz: bcaeec04d22f9a472d19777fcc607e27c84d42ad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 59f8a36ce57a130e0f5f7c5614ca6642e4e3b2c31207960e8dfe7f1c2a5d1d23ec5959955df843a63d412eec6b5568b0451dda4f267d4a0c2cde8f0ba49e2a1f
|
7
|
+
data.tar.gz: daaf4b414679b21c6d61a0ceb27f0d475d6262afd4073eede9e1e4453499dace3ad0ffd73b07a3e7a3e629b3eff4f6ce25f5e1004d821a225e54b21ba2016934
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Houcho
|
2
2
|
- wrapping to execute serverspec
|
3
|
-
- depends on ruby 1.9 later.
|
3
|
+
- depends on ruby 1.9 later(recommended: 2.0 later).
|
4
4
|
|
5
5
|
## Install and Initialize
|
6
6
|
- install houcho from ruby gems
|
@@ -142,4 +142,6 @@ $ houcho role exec studio3104::www --exclude-hosts studio3104.test
|
|
142
142
|
```
|
143
143
|
|
144
144
|
## TODO
|
145
|
-
-
|
145
|
+
- write more tests
|
146
|
+
- `Houcho::Logger`
|
147
|
+
- LTSV
|
data/bin/houcho
CHANGED
@@ -54,21 +54,24 @@ class SpecConduct < Thor::MyHelper
|
|
54
54
|
option :roles, :type => :array, :required => true, :desc => 'specify the roles separated by spaces.'
|
55
55
|
def attach(*args)
|
56
56
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
57
|
-
Spec.attach(args, options[:roles])
|
57
|
+
Spec.attach(args, options[:roles]) rescue puts $!.message; exit!
|
58
58
|
end
|
59
59
|
|
60
60
|
desc 'detach [spec1 spec2 spec3...] --roles [role1 role2...]', 'detach spec from spec'
|
61
61
|
option :roles, :type => :array, :required => true, :desc => 'specify the roles separated by spaces.'
|
62
62
|
def detach(*args)
|
63
63
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
64
|
-
Spec.detach(args, options[:roles])
|
64
|
+
Spec.detach(args, options[:roles]) rescue puts $!.message; exit!
|
65
65
|
end
|
66
66
|
|
67
67
|
desc 'check [options]', 'run the spec sampled appropriately to the associated host'
|
68
68
|
option :sample_host_count, :type => :numeric, :default => 5, :desc => 'number of sample hosts'
|
69
69
|
def check(*args)
|
70
70
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
71
|
-
Spec::Runner.check(args, options[:sample_host_count])
|
71
|
+
messages = Spec::Runner.check(args, options[:sample_host_count]) rescue puts $!.message; exit!
|
72
|
+
messages.each do |msg|
|
73
|
+
puts msg
|
74
|
+
end
|
72
75
|
end
|
73
76
|
|
74
77
|
desc 'exec (spec1 spec2..) [options]', 'run serverspec manually'
|
@@ -79,14 +82,18 @@ class SpecConduct < Thor::MyHelper
|
|
79
82
|
def exec(*args)
|
80
83
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
81
84
|
|
82
|
-
Spec::Runner.exec(
|
85
|
+
messages = Spec::Runner.exec(
|
83
86
|
[], [], options[:hosts], args,
|
84
87
|
{
|
85
88
|
ukigumo: options[:ukigumo],
|
86
89
|
ikachan: options[:ikachan],
|
87
90
|
},
|
88
91
|
options[:dry_run],
|
89
|
-
)
|
92
|
+
) rescue puts $!.message; exit!
|
93
|
+
|
94
|
+
messages.each do |msg|
|
95
|
+
puts msg
|
96
|
+
end
|
90
97
|
end
|
91
98
|
end
|
92
99
|
|
@@ -109,14 +116,14 @@ class HostConduct < Thor::MyHelper
|
|
109
116
|
option :roles, :type => :array, :required => true, :desc => 'specify the roles separated by spaces.'
|
110
117
|
def attach(*args)
|
111
118
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
112
|
-
Host.attach(args, options[:roles])
|
119
|
+
Host.attach(args, options[:roles]) rescue puts $!.message; exit!
|
113
120
|
end
|
114
121
|
|
115
122
|
desc 'detach [host1 host2 host3...] --roles [role1 role2...]', 'detach host from role'
|
116
123
|
option :roles, :type => :array, :required => true, :desc => 'specify the roles separated by spaces.'
|
117
124
|
def detach(*args)
|
118
125
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
119
|
-
Host.detach(args, options[:roles])
|
126
|
+
Host.detach(args, options[:roles]) rescue puts $!.message; exit!
|
120
127
|
end
|
121
128
|
end
|
122
129
|
|
@@ -127,18 +134,18 @@ class RoleConduct < Thor::MyHelper
|
|
127
134
|
desc 'create [role1 role2 role3...]', 'cretate role'
|
128
135
|
def create(*args)
|
129
136
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
130
|
-
Role.create(args)
|
137
|
+
Role.create(args) rescue puts $!.message; exit!
|
131
138
|
end
|
132
139
|
|
133
140
|
desc 'delete [role1 role2 role3...]', 'delete a role'
|
134
141
|
def delete(*args)
|
135
142
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
136
|
-
Role.delete(args)
|
143
|
+
Role.delete(args) rescue puts $!.message; exit!
|
137
144
|
end
|
138
145
|
|
139
146
|
desc 'rename [exist role] [name]', 'rename a role'
|
140
147
|
def rename(role, rename)
|
141
|
-
Role.rename(role, rename)
|
148
|
+
Role.rename(role, rename) rescue puts $!.message; exit!
|
142
149
|
end
|
143
150
|
|
144
151
|
desc 'details [role1 role2...]', 'show details about role'
|
@@ -160,14 +167,18 @@ class RoleConduct < Thor::MyHelper
|
|
160
167
|
def exec(*args)
|
161
168
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
162
169
|
|
163
|
-
Spec::Runner.exec(
|
170
|
+
messages = Spec::Runner.exec(
|
164
171
|
args, (options[:exclude_hosts]||[]), [], [],
|
165
172
|
{
|
166
173
|
ukigumo: options[:ukigumo],
|
167
174
|
ikachan: options[:ikachan],
|
168
175
|
},
|
169
176
|
options[:dry_run],
|
170
|
-
)
|
177
|
+
) rescue puts $!.message; exit!
|
178
|
+
|
179
|
+
messages.each do |msg|
|
180
|
+
puts msg
|
181
|
+
end
|
171
182
|
end
|
172
183
|
end
|
173
184
|
|
@@ -190,14 +201,14 @@ class CFConduct < Thor::MyHelper
|
|
190
201
|
option :roles, :type => :array, :required => true, :desc => 'specify the roles separated by spaces.'
|
191
202
|
def attach(*args)
|
192
203
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
193
|
-
CloudForecast::Role.attach(args, options[:roles])
|
204
|
+
CloudForecast::Role.attach(args, options[:roles]) rescue puts $!.message; exit!
|
194
205
|
end
|
195
206
|
|
196
207
|
desc 'detach [cf1 cf2 cf3...] --roles [role1 role2...]', "detach cloudforecast's role from role"
|
197
208
|
option :roles, :type => :array, :required => true, :desc => 'specify the roles separated by spaces.'
|
198
209
|
def detach(*args)
|
199
210
|
Helper.empty_args(self, shell, __method__) if args.empty?
|
200
|
-
CloudForecast::Role.detach(args, options[:roles])
|
211
|
+
CloudForecast::Role.detach(args, options[:roles]) rescue puts $!.message; exit!
|
201
212
|
end
|
202
213
|
|
203
214
|
desc 'load', '(re)loading yamls of cloudforecast'
|
@@ -226,7 +237,7 @@ class Main < Thor
|
|
226
237
|
|
227
238
|
desc 'init', 'set houcho repository on current directory'
|
228
239
|
def init
|
229
|
-
|
240
|
+
init_repo
|
230
241
|
end
|
231
242
|
|
232
243
|
end
|
data/houcho.gemspec
CHANGED
@@ -18,10 +18,13 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_runtime_dependency 'thor'
|
21
22
|
spec.add_runtime_dependency 'rainbow'
|
22
23
|
spec.add_runtime_dependency 'parallel_tests'
|
23
24
|
spec.add_runtime_dependency 'systemu'
|
24
25
|
spec.add_runtime_dependency 'serverspec'
|
25
26
|
spec.add_development_dependency "bundler", "~> 1.3"
|
26
27
|
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "tmpdir"
|
29
|
+
spec.add_development_dependency "tempfile"
|
27
30
|
end
|
data/lib/houcho.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require '
|
2
|
+
require 'fileutils'
|
3
3
|
require 'rainbow'
|
4
|
-
require 'parallel'
|
5
4
|
require 'systemu'
|
6
5
|
require 'tempfile'
|
7
6
|
require 'find'
|
8
7
|
require 'yaml'
|
9
8
|
require 'json'
|
10
|
-
require 'houcho/initialize'
|
11
9
|
require 'houcho/yamlhandle'
|
12
10
|
require 'houcho/element'
|
13
11
|
require 'houcho/role'
|
@@ -20,6 +18,19 @@ require 'houcho/cloudforecast/host'
|
|
20
18
|
require 'houcho/ci'
|
21
19
|
|
22
20
|
module Houcho
|
21
|
+
def init_repo
|
22
|
+
templates = File.expand_path("#{File.dirname(__FILE__)}/../templates")
|
23
|
+
|
24
|
+
%W{conf role spec}.each do |d|
|
25
|
+
FileUtils.cp_r("#{templates}/#{d}", d) if ! Dir.exist?(d)
|
26
|
+
end
|
27
|
+
|
28
|
+
File.symlink('./conf/rspec.conf', './.rspec') if ! File.exists? '.rspec'
|
29
|
+
|
30
|
+
`git init; git add .; git commit -a -m 'initialized houcho repository'` if ! Dir.exist?('.git')
|
31
|
+
end
|
32
|
+
|
33
|
+
|
23
34
|
def puts_details(e, indentsize = 0, cnt = 1)
|
24
35
|
case e
|
25
36
|
when Array
|
data/lib/houcho/cloudforecast.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
1
|
module Houcho
|
2
|
-
module CloudForecast
|
3
|
-
|
2
|
+
module CloudForecast
|
3
|
+
class Host
|
4
|
+
def initialize
|
5
|
+
@cf = YamlHandle::Loader.new('./role/cloudforecast.yaml')
|
6
|
+
end
|
4
7
|
|
5
|
-
|
8
|
+
def roles(host)
|
9
|
+
@cf.data.select {|cfrole, cfhosts|cfhosts.include?(host)}.keys
|
10
|
+
end
|
6
11
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def hosts(role)
|
12
|
-
@cfdata[role] || []
|
13
|
-
end
|
12
|
+
def hosts(role)
|
13
|
+
@cf.data[role] || []
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def details(host)
|
17
|
+
CloudForecast::Role.details(roles(host))
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
def all
|
21
|
+
@cf.data.values.flatten.uniq
|
22
|
+
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -7,12 +7,13 @@ module Houcho
|
|
7
7
|
def self.details(cfroles)
|
8
8
|
result = {}
|
9
9
|
cfroles.each do |cfrole|
|
10
|
-
hosts = CloudForecast::Host.hosts(cfrole)
|
10
|
+
hosts = CloudForecast::Host.new.hosts(cfrole)
|
11
11
|
if ! hosts.empty?
|
12
12
|
result[cfrole] = {}
|
13
13
|
result[cfrole]['host'] = hosts
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
16
17
|
result
|
17
18
|
end
|
18
19
|
|
data/lib/houcho/element.rb
CHANGED
@@ -24,7 +24,7 @@ module Houcho
|
|
24
24
|
end
|
25
25
|
|
26
26
|
@elements.save_to_file
|
27
|
-
|
27
|
+
raise("role(#{invalid_roles.join(',')}) does not exist") if ! invalid_roles.size.zero?
|
28
28
|
end
|
29
29
|
|
30
30
|
|
@@ -41,7 +41,7 @@ module Houcho
|
|
41
41
|
end
|
42
42
|
|
43
43
|
@elements.save_to_file
|
44
|
-
|
44
|
+
raise("role(#{invalid_roles.join(',')}) does not exist") if ! invalid_roles.size.zero?
|
45
45
|
end
|
46
46
|
|
47
47
|
|
data/lib/houcho/host.rb
CHANGED
@@ -8,7 +8,7 @@ module Houcho
|
|
8
8
|
|
9
9
|
hosts.each do |host|
|
10
10
|
roles = self.indexes(host).map {|index|Role.name(index)}
|
11
|
-
cfroles = CloudForecast::Host.roles(host)
|
11
|
+
cfroles = CloudForecast::Host.new.roles(host)
|
12
12
|
|
13
13
|
result[host] = {}
|
14
14
|
result[host]['role'] = roles if ! roles.empty?
|
data/lib/houcho/role.rb
CHANGED
@@ -15,7 +15,7 @@ module Houcho
|
|
15
15
|
|
16
16
|
if role.size == 0
|
17
17
|
@roles.save_to_file
|
18
|
-
|
18
|
+
raise("role(#{exists.join(',')}) already exist.") if exists.size != 0
|
19
19
|
else
|
20
20
|
self.create(role, exists)
|
21
21
|
end
|
@@ -49,7 +49,7 @@ module Houcho
|
|
49
49
|
e << "detach host from #{errors[:hosts].join(',')} before delete" if ! errors[:hosts].size.zero?
|
50
50
|
e << "detach spec from #{errors[:specs].join(',')} before delete" if ! errors[:specs].size.zero?
|
51
51
|
e << "detach cloudforecast's role from #{errors[:cf].join(',')} before delete" if ! errors[:cf].size.zero?
|
52
|
-
|
52
|
+
raise("#{e.join(', ')}.") if ! e.size.zero?
|
53
53
|
else
|
54
54
|
self.delete(role, errors)
|
55
55
|
end
|
@@ -58,8 +58,8 @@ module Houcho
|
|
58
58
|
|
59
59
|
def rename(role, name)
|
60
60
|
index = self.index(role)
|
61
|
-
|
62
|
-
|
61
|
+
raise("#{role} does not exist") if ! index
|
62
|
+
raise("#{name} already exist") if self.index(name)
|
63
63
|
|
64
64
|
@roles.data[index] = name
|
65
65
|
@roles.save_to_file
|
data/lib/houcho/spec/runner.rb
CHANGED
@@ -26,27 +26,27 @@ module Houcho
|
|
26
26
|
end
|
27
27
|
|
28
28
|
m = {}
|
29
|
-
m['host'] = hosts
|
30
|
-
m['spec'] = spec_check.call(specs)
|
29
|
+
m['host'] = hosts if ! hosts.empty?
|
30
|
+
m['spec'] = spec_check.call(specs) if ! specs.empty?
|
31
31
|
|
32
32
|
runlist[:'run manually'] = m if m != {}
|
33
33
|
|
34
34
|
if ! spec_not_exist.empty?
|
35
|
-
|
36
|
-
puts "spec(#{spec_not_exist.join(',')}) file not exist in ./spec directory."
|
35
|
+
raise "spec(#{spec_not_exist.join(',')}) file not exist in ./spec directory."
|
37
36
|
end
|
38
37
|
runlist
|
39
38
|
end
|
40
39
|
|
41
40
|
|
42
41
|
def exec(roles, ex_hosts, hosts, specs, ci = {}, dryrun = nil)
|
42
|
+
messages = []
|
43
43
|
self.prepare(roles, ex_hosts, hosts, specs).each do |role, v|
|
44
44
|
next if v['spec'].empty?
|
45
45
|
command = "parallel_rspec #{v['spec'].sort.uniq.join(' ')}"
|
46
46
|
|
47
47
|
if dryrun
|
48
48
|
v['host'].each do |host|
|
49
|
-
|
49
|
+
messages << "TARGET_HOST=#{host} #{command}"
|
50
50
|
end
|
51
51
|
next
|
52
52
|
end
|
@@ -54,12 +54,13 @@ module Houcho
|
|
54
54
|
v['host'].each do |host|
|
55
55
|
ENV['TARGET_HOST'] = host
|
56
56
|
result = systemu command
|
57
|
-
|
57
|
+
messages << result[1].scan(/\d* examples?, \d* failures?\n/).first.chomp + "\t#{host}, #{command}\n"
|
58
58
|
|
59
59
|
post_result(result, role, host, command, ci) if ci != {}
|
60
60
|
$houcho_fail = true if result[0] != 0
|
61
61
|
end
|
62
62
|
end
|
63
|
+
messages
|
63
64
|
end
|
64
65
|
|
65
66
|
|
@@ -91,25 +92,33 @@ module Houcho
|
|
91
92
|
end
|
92
93
|
|
93
94
|
|
94
|
-
def check(specs, host_count)
|
95
|
-
specs
|
95
|
+
def check(specs, host_count, dryrun = false) # dryrun is for test
|
96
|
+
specs = specs.flatten
|
97
|
+
error = []
|
98
|
+
messages = []
|
96
99
|
|
97
100
|
specs.each do |spec|
|
98
101
|
hosts = []
|
99
102
|
indexes = Spec.indexes(spec)
|
100
103
|
|
101
104
|
if indexes.empty?
|
102
|
-
|
105
|
+
error << spec
|
103
106
|
next
|
104
107
|
end
|
105
108
|
|
106
109
|
indexes.each do |index|
|
107
110
|
hosts += Host.elements(index)
|
108
111
|
CloudForecast::Role.elements(index).each do |cfrole|
|
109
|
-
hosts += CloudForecast::Host(cfrole)
|
112
|
+
hosts += CloudForecast::Host.new.hosts(cfrole)
|
110
113
|
end
|
111
114
|
end
|
112
|
-
hosts.sample(host_count).each {|host| exec([], [], [host], [spec])}
|
115
|
+
hosts.sample(host_count).each {|host| messages += exec([], [], [host], [spec], {}, dryrun)}
|
116
|
+
end
|
117
|
+
|
118
|
+
if error.empty?
|
119
|
+
messages
|
120
|
+
else
|
121
|
+
raise("role(#{error.join(',')}) has not attached to any roles")
|
113
122
|
end
|
114
123
|
end
|
115
124
|
end
|
data/lib/houcho/version.rb
CHANGED
data/lib/houcho/yamlhandle.rb
CHANGED
@@ -4,7 +4,11 @@ module Houcho
|
|
4
4
|
attr_reader :data
|
5
5
|
|
6
6
|
def initialize(yaml_file)
|
7
|
-
|
7
|
+
begin
|
8
|
+
@data = YAML.load_file(yaml_file)
|
9
|
+
rescue
|
10
|
+
# I think it should describe the process when current directory has not ready for houcho
|
11
|
+
end
|
8
12
|
@data ||= {}
|
9
13
|
end
|
10
14
|
end
|
data/spec/houcho_spec.rb
CHANGED
@@ -1,7 +1,164 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
spectmp = Dir.mktmpdir('spec')
|
4
|
+
include Houcho
|
5
|
+
|
6
|
+
describe Houcho do
|
7
|
+
before :all do
|
8
|
+
Dir.chdir(spectmp)
|
9
|
+
init_repo
|
10
|
+
Role.create(['studio3104', 'studio3105'])
|
11
|
+
Host.attach(['hostA'], ['studio3104'])
|
12
|
+
|
13
|
+
File.write('spec/specA_spec.rb',' ')
|
14
|
+
Spec.attach(['specA'], ['studio3104'])
|
15
|
+
|
16
|
+
File.write('./role/cloudforecast/cf.yaml', <<EOD
|
17
|
+
--- #houcho
|
18
|
+
servers:
|
19
|
+
- label: rspec
|
20
|
+
config: studio3104
|
21
|
+
hosts:
|
22
|
+
- test1.studio3104.com
|
23
|
+
- test2.studio3104.com
|
24
|
+
EOD
|
25
|
+
)
|
26
|
+
CloudForecast.load_yaml
|
27
|
+
CloudForecast::Role.attach(['houcho::rspec::studio3104'], ['studio3104'])
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe Role do
|
32
|
+
context 'create and delete a role' do
|
33
|
+
it { Role.create(['www']) }
|
34
|
+
it { expect { Role.create(['www']) }.to raise_error }
|
35
|
+
it { Role.delete(['www']) }
|
36
|
+
it { expect { Role.delete(['web']) }.to raise_error }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'create and delete two roles' do
|
40
|
+
it { Role.create(['studio3104::www', 'studio3104::database']) }
|
41
|
+
it { expect { Role.create(['studio3104::www', 'studio3104::database']) }.to raise_error }
|
42
|
+
it { Role.delete(['studio3104::www', 'studio3104::database']) }
|
43
|
+
it { expect { Role.delete(['studio3104::www', 'studio3104::database']) }.to raise_error }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'rename a role' do
|
47
|
+
it { Role.rename('studio3105', 'studio3106') }
|
48
|
+
it { expect { Role.rename('invalid_role', 'studio3106') }.to raise_error }
|
49
|
+
it { expect { Role.rename('studio3106', 'studio3104') }.to raise_error }
|
50
|
+
it { Role.rename('studio3106', 'studio3105') }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'get all roles' do
|
54
|
+
it { Role.all.should eq ['studio3104', 'studio3105'] }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'get details of a role' do
|
58
|
+
it do
|
59
|
+
expect(Role.details(['studio3104'])).to eq(
|
60
|
+
{
|
61
|
+
'studio3104' => {
|
62
|
+
'host' => [ 'hostA' ],
|
63
|
+
'spec' => [ 'specA' ],
|
64
|
+
'cf' => { 'houcho::rspec::studio3104' => { 'host' => [ 'test1.studio3104.com', 'test2.studio3104.com', ] } }
|
65
|
+
}
|
66
|
+
}
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it { expect(Role.index('studio3104')).to be(1)}
|
72
|
+
it { expect(Role.indexes_regexp(/studio310\d/)).to eq([1,2])}
|
73
|
+
it { expect(Role.name(1)).to eq('studio3104')}
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
describe Houcho::Host do
|
78
|
+
context 'attach and detach hosts to roles' do
|
79
|
+
it { Host.attach(['host1', 'host2'], ['studio3104', 'studio3105']) }
|
80
|
+
it { expect { Host.attach(['host1'], ['invalid_role']) }.to raise_error }
|
81
|
+
it { Host.detach(['host1', 'host2'], ['studio3104', 'studio3105']) }
|
82
|
+
it { expect { Host.detach(['host1'], ['invalid_role']) }.to raise_error }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'get details of a host' do
|
86
|
+
it 'host from original defined' do
|
87
|
+
expect(Host.details(['hostA'])).to eq(
|
88
|
+
{ 'hostA' => { 'role' => [ 'studio3104' ] } }
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'host from cf defined' do
|
93
|
+
expect(Host.details(['test1.studio3104.com'])).to eq(
|
94
|
+
{ 'test1.studio3104.com' => { 'cf' => [ 'houcho::rspec::studio3104' ] } }
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'both' do
|
99
|
+
expect(Host.details(['hostA', 'test1.studio3104.com'])).to eq(
|
100
|
+
{
|
101
|
+
'hostA' => { 'role' => [ 'studio3104' ] },
|
102
|
+
'test1.studio3104.com' => { 'cf' => [ 'houcho::rspec::studio3104' ] },
|
103
|
+
}
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'get host list attached or defined cf' do
|
108
|
+
it 'all of hosts' do
|
109
|
+
expect(Host.elements).to eq(["hostA"])
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'hosts of one of role' do
|
113
|
+
expect(Host.elements(1)).to eq(["hostA"])
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
describe Houcho::Spec::Runner do
|
121
|
+
context 'run role' do
|
122
|
+
it do
|
123
|
+
expect(Spec::Runner.exec(['studio3104'],[],[],[],{},true)).to eq([
|
124
|
+
'TARGET_HOST=hostA parallel_rspec spec/specA_spec.rb',
|
125
|
+
'TARGET_HOST=test1.studio3104.com parallel_rspec spec/specA_spec.rb',
|
126
|
+
'TARGET_HOST=test2.studio3104.com parallel_rspec spec/specA_spec.rb'
|
127
|
+
])
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'with exclude host' do
|
131
|
+
expect(Spec::Runner.exec(['studio3104'],['test1.studio3104.com'],[],[],{},true)).to eq([
|
132
|
+
'TARGET_HOST=hostA parallel_rspec spec/specA_spec.rb',
|
133
|
+
'TARGET_HOST=test2.studio3104.com parallel_rspec spec/specA_spec.rb'
|
134
|
+
])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'run manually' do
|
139
|
+
it do
|
140
|
+
expect(Spec::Runner.exec([],[],['test3.studio3104.com', 'test4.studio3104.com'],['specA'],{},true)).to eq([
|
141
|
+
'TARGET_HOST=test3.studio3104.com parallel_rspec spec/specA_spec.rb',
|
142
|
+
'TARGET_HOST=test4.studio3104.com parallel_rspec spec/specA_spec.rb'
|
143
|
+
])
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'case of spec not exist' do
|
147
|
+
expect { Spec::Runner.exec([],[],['test5.studio3104.com'],['specA', 'specX'],{},true) }.to raise_error
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'check spec' do
|
152
|
+
it { expect(Spec::Runner.check(['specA'], 2, true).size).to be(2) }
|
153
|
+
it 'case of spec not exist' do
|
154
|
+
expect { Spec::Runner.check(['specX'], 2, true) }.to raise_error
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
after :all do
|
161
|
+
Dir.chdir('/')
|
162
|
+
FileUtils.rm_rf(spectmp)
|
6
163
|
end
|
7
164
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,9 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
require 'rspec'
|
4
4
|
require 'houcho'
|
5
|
+
require 'tmpdir'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'fileutils'
|
5
8
|
|
6
9
|
# Requires supporting files with custom matchers and macros, etc,
|
7
10
|
# in ./support/ and its subdirectories.
|
File without changes
|
metadata
CHANGED
@@ -1,69 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: houcho
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Satoshi SUZUKI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rainbow
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- -
|
31
|
+
- - '>='
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '0'
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- -
|
38
|
+
- - '>='
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: parallel_tests
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - '>='
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '0'
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - '>='
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: systemu
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - '>='
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '0'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - '>='
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: serverspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - '>='
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - '>='
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
@@ -84,14 +98,42 @@ dependencies:
|
|
84
98
|
name: rake
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- -
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: tmpdir
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: tempfile
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
88
130
|
- !ruby/object:Gem::Version
|
89
131
|
version: '0'
|
90
132
|
type: :development
|
91
133
|
prerelease: false
|
92
134
|
version_requirements: !ruby/object:Gem::Requirement
|
93
135
|
requirements:
|
94
|
-
- -
|
136
|
+
- - '>='
|
95
137
|
- !ruby/object:Gem::Version
|
96
138
|
version: '0'
|
97
139
|
description: covering to run serverspec
|
@@ -116,7 +158,6 @@ files:
|
|
116
158
|
- lib/houcho/cloudforecast/role.rb
|
117
159
|
- lib/houcho/element.rb
|
118
160
|
- lib/houcho/host.rb
|
119
|
-
- lib/houcho/initialize.rb
|
120
161
|
- lib/houcho/role.rb
|
121
162
|
- lib/houcho/spec.rb
|
122
163
|
- lib/houcho/spec/runner.rb
|
@@ -130,6 +171,7 @@ files:
|
|
130
171
|
- templates/master
|
131
172
|
- templates/role/cf_roles.yaml
|
132
173
|
- templates/role/cloudforecast.yaml
|
174
|
+
- templates/role/cloudforecast/.gitkeep
|
133
175
|
- templates/role/hosts.yaml
|
134
176
|
- templates/role/hosts_ignored.yaml
|
135
177
|
- templates/role/roles.yaml
|
@@ -146,17 +188,17 @@ require_paths:
|
|
146
188
|
- lib
|
147
189
|
required_ruby_version: !ruby/object:Gem::Requirement
|
148
190
|
requirements:
|
149
|
-
- -
|
191
|
+
- - '>='
|
150
192
|
- !ruby/object:Gem::Version
|
151
193
|
version: '0'
|
152
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
195
|
requirements:
|
154
|
-
- -
|
196
|
+
- - '>='
|
155
197
|
- !ruby/object:Gem::Version
|
156
198
|
version: '0'
|
157
199
|
requirements: []
|
158
200
|
rubyforge_project:
|
159
|
-
rubygems_version: 2.0.
|
201
|
+
rubygems_version: 2.0.2
|
160
202
|
signing_key:
|
161
203
|
specification_version: 4
|
162
204
|
summary: covering to run serverspec
|
data/lib/houcho/initialize.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
module Houcho
|
4
|
-
module Initialize
|
5
|
-
templates = File.expand_path("#{File.dirname(__FILE__)}/../../templates")
|
6
|
-
|
7
|
-
%W{conf role spec}.each do |d|
|
8
|
-
FileUtils.cp_r("#{templates}/#{d}", d) if ! Dir.exist?(d)
|
9
|
-
end
|
10
|
-
|
11
|
-
File.symlink('./conf/rspec.conf', './.rspec') if ! File.exists? '.rspec'
|
12
|
-
|
13
|
-
`git init; git add .; git commit -a -m 'initialized houcho repository'` if ! Dir.exist?('.git')
|
14
|
-
end
|
15
|
-
end
|