dk 0.0.1 → 0.1.0

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.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +643 -1
  3. data/bin/dk +7 -0
  4. data/dk.gemspec +7 -3
  5. data/lib/dk/ansi.rb +98 -0
  6. data/lib/dk/cli.rb +173 -0
  7. data/lib/dk/config.rb +217 -0
  8. data/lib/dk/config_runner.rb +24 -0
  9. data/lib/dk/dk_runner.rb +13 -0
  10. data/lib/dk/dry_runner.rb +43 -0
  11. data/lib/dk/has_set_param.rb +42 -0
  12. data/lib/dk/has_ssh_opts.rb +36 -0
  13. data/lib/dk/has_the_runs.rb +23 -0
  14. data/lib/dk/has_the_stubs.rb +116 -0
  15. data/lib/dk/local.rb +84 -0
  16. data/lib/dk/null_logger.rb +13 -0
  17. data/lib/dk/remote.rb +132 -0
  18. data/lib/dk/runner.rb +202 -0
  19. data/lib/dk/task.rb +266 -0
  20. data/lib/dk/task_run.rb +17 -0
  21. data/lib/dk/test_runner.rb +54 -0
  22. data/lib/dk/tree_runner.rb +64 -0
  23. data/lib/dk/version.rb +1 -1
  24. data/lib/dk.rb +23 -1
  25. data/test/helper.rb +6 -1
  26. data/test/support/config/dk.rb +7 -0
  27. data/test/support/config/task_defs.rb +10 -0
  28. data/test/support/factory.rb +38 -0
  29. data/test/support/log/.gitkeep +0 -0
  30. data/test/system/has_the_stubs_tests.rb +355 -0
  31. data/test/system/runner_tests.rb +222 -0
  32. data/test/unit/ansi_tests.rb +40 -0
  33. data/test/unit/cli_tests.rb +317 -0
  34. data/test/unit/config_runner_tests.rb +60 -0
  35. data/test/unit/config_tests.rb +427 -0
  36. data/test/unit/dk_runner_tests.rb +34 -0
  37. data/test/unit/dk_tests.rb +49 -0
  38. data/test/unit/dry_runner_tests.rb +71 -0
  39. data/test/unit/has_set_param_tests.rb +46 -0
  40. data/test/unit/has_ssh_opts_tests.rb +81 -0
  41. data/test/unit/has_the_runs_tests.rb +37 -0
  42. data/test/unit/has_the_stubs_tests.rb +279 -0
  43. data/test/unit/local_tests.rb +174 -0
  44. data/test/unit/null_logger_tests.rb +17 -0
  45. data/test/unit/remote_tests.rb +330 -0
  46. data/test/unit/runner_tests.rb +398 -0
  47. data/test/unit/task_run_tests.rb +40 -0
  48. data/test/unit/task_tests.rb +943 -0
  49. data/test/unit/test_runner_tests.rb +189 -0
  50. data/test/unit/tree_runner_tests.rb +152 -0
  51. metadata +106 -9
@@ -0,0 +1,330 @@
1
+ require 'assert'
2
+ require 'dk/remote'
3
+
4
+ require 'dk/local'
5
+
6
+ module Dk::Remote
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "Dk::Remote"
10
+ setup do
11
+ @hosts = Factory.hosts
12
+ @ssh_args = Factory.string
13
+ @host_ssh_args = { @hosts.sample => Factory.string }
14
+ @cmd_str = Factory.string
15
+
16
+ @opts = {
17
+ :env => { Factory.string => Factory.string },
18
+ :dry_tree_run => Factory.boolean,
19
+ :hosts => @hosts,
20
+ :ssh_args => @ssh_args,
21
+ :host_ssh_args => @host_ssh_args,
22
+ Factory.string => Factory.string
23
+ }
24
+
25
+ @local_cmd_new_called_with = nil
26
+ Assert.stub(Dk::Local::Cmd, :new) do |*args|
27
+ @local_cmd_new_called_with = args
28
+ Assert.stub_send(Dk::Local::Cmd, :new, *args)
29
+ end
30
+
31
+ @local_cmd_spy_new_called_with = nil
32
+ Assert.stub(Dk::Local::CmdSpy, :new) do |*args|
33
+ @local_cmd_spy_new_called_with = args
34
+ Assert.stub_send(Dk::Local::CmdSpy, :new, *args).tap do |spy|
35
+ spy.exitstatus = Factory.exitstatus
36
+ spy.stdout = [Factory.stdout, nil].sample
37
+ spy.stderr = [Factory.stderr, nil].sample
38
+ end
39
+ end
40
+
41
+ @remote_class = Dk::Remote
42
+ end
43
+ subject{ @remote_class }
44
+
45
+ should have_imeths :ssh_cmd_str
46
+
47
+ should "build ssh cmd strs" do
48
+ h = @host_ssh_args.keys.first
49
+ exp = ssh_cmd_str(@cmd_str, h, @ssh_args, @host_ssh_args)
50
+ assert_equal exp, subject.ssh_cmd_str(@cmd_str, h, @ssh_args, @host_ssh_args)
51
+ end
52
+
53
+ private
54
+
55
+ def ssh_cmd_str(cmd_str, host, args, host_args)
56
+ val = "\"#{cmd_str}\"".gsub("\\", "\\\\\\").gsub('"', '\"')
57
+ "ssh #{args} #{host_args[host]} #{host} -- \"sh -c #{val}\""
58
+ end
59
+
60
+ end
61
+
62
+ class BaseCmdTests < UnitTests
63
+ desc "BaseCmd"
64
+ setup do
65
+ @cmd_class = @remote_class::BaseCmd
66
+ @cmd = @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, @opts)
67
+ end
68
+ subject{ @cmd }
69
+
70
+ should have_readers :hosts, :ssh_args, :host_ssh_args, :cmd_str, :local_cmds
71
+ should have_imeths :to_s, :ssh_cmd_str, :run
72
+ should have_imeths :stdout, :stderr, :success?, :output_lines
73
+
74
+ should "know its hosts" do
75
+ assert_equal @hosts.sort, subject.hosts
76
+ end
77
+
78
+ should "complain if not given any hosts" do
79
+ assert_raises(NoHostsError) do
80
+ @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, :hosts => nil)
81
+ end
82
+ assert_raises(NoHostsError) do
83
+ @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, :hosts => Factory.integer)
84
+ end
85
+ assert_raises(NoHostsError) do
86
+ @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, :hosts => [])
87
+ end
88
+ assert_raises(NoHostsError) do
89
+ @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, :hosts => [nil])
90
+ end
91
+ assert_raises(NoHostsError) do
92
+ @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, :hosts => [Factory.string, nil])
93
+ end
94
+ assert_raises(NoHostsError) do
95
+ @cmd_class.new(Dk::Local::CmdSpy, @cmd_str, :hosts => [nil, Factory.string])
96
+ end
97
+ end
98
+
99
+ should "know its ssh args" do
100
+ assert_equal @ssh_args, subject.ssh_args
101
+ assert_equal @host_ssh_args, subject.host_ssh_args
102
+ end
103
+
104
+ should "know its cmd str" do
105
+ assert_equal @cmd_str, subject.cmd_str
106
+ assert_equal subject.cmd_str, subject.to_s
107
+ end
108
+
109
+ should "build ssh cmd strs given a host" do
110
+ host = Factory.string
111
+ exp = @remote_class.ssh_cmd_str(@cmd_str, host, @ssh_args, @host_ssh_args)
112
+ assert_equal exp, subject.ssh_cmd_str(host)
113
+ end
114
+
115
+ should "build a local cmd for each of its hosts" do
116
+ subject.hosts.each do |host|
117
+ assert_instance_of Dk::Local::CmdSpy, subject.local_cmds[host]
118
+ exp = subject.ssh_cmd_str(host)
119
+ assert_equal exp, subject.local_cmds[host].cmd_str
120
+ end
121
+ exp_cmd_str = subject.ssh_cmd_str(subject.hosts.last)
122
+ exp_opts = {
123
+ :env => @opts[:env],
124
+ :dry_tree_run => @opts[:dry_tree_run]
125
+ }
126
+ assert_equal [exp_cmd_str, exp_opts], @local_cmd_spy_new_called_with
127
+
128
+ cmd = @cmd_class.new(Dk::Local::Cmd, @cmd_str, @opts)
129
+ cmd.hosts.each do |host|
130
+ assert_instance_of Dk::Local::Cmd, cmd.local_cmds[host]
131
+ exp = subject.ssh_cmd_str(host)
132
+ assert_equal exp, cmd.local_cmds[host].cmd_str
133
+ end
134
+ exp_cmd_str = subject.ssh_cmd_str(cmd.hosts.last)
135
+ exp_opts = {
136
+ :env => @opts[:env],
137
+ :dry_tree_run => @opts[:dry_tree_run]
138
+ }
139
+ assert_equal [exp_cmd_str, exp_opts], @local_cmd_new_called_with
140
+ end
141
+
142
+ should "start and wait on each of its local cmds' scmd when run" do
143
+ subject.hosts.each do |host|
144
+ assert_false subject.local_cmds[host].scmd.start_called?
145
+ assert_false subject.local_cmds[host].scmd.wait_called?
146
+ end
147
+
148
+ input = Factory.string
149
+ subject.run(input)
150
+
151
+ subject.hosts.each do |host|
152
+ assert_true subject.local_cmds[host].scmd.start_called?
153
+ assert_true subject.local_cmds[host].scmd.wait_called?
154
+ assert_equal input, subject.local_cmds[host].scmd.start_calls.last.input
155
+ end
156
+ end
157
+
158
+ should "use the stdout/stderr of the first non-empty stdout/stderr" do
159
+ outs = subject.hosts.map{ |h| subject.local_cmds[h].stdout.to_s }
160
+ exp = outs.find{ |o| !o.empty? } || ''
161
+ assert_equal exp, subject.stdout
162
+
163
+ errs = subject.hosts.map{ |h| subject.local_cmds[h].stderr.to_s }
164
+ exp = errs.find{ |e| !e.empty? } || ''
165
+ assert_equal exp, subject.stderr
166
+ end
167
+
168
+ should "know whether it was successful or not" do
169
+ subject.hosts.each do |host|
170
+ Assert.stub(subject.local_cmds[host], :success?){ true }
171
+ end
172
+ assert_true subject.success?
173
+
174
+ Assert.stub(subject.local_cmds[subject.hosts.sample], :success?){ false }
175
+ assert_false subject.success?
176
+ end
177
+
178
+ should "know its output lines" do
179
+ exp = []
180
+ subject.hosts.each do |host|
181
+ subject.local_cmds[host].output_lines.each do |ol|
182
+ exp << [host, ol]
183
+ end
184
+ end
185
+ output_lines = subject.output_lines
186
+
187
+ assert_equal exp.size, output_lines.size
188
+
189
+ if output_lines.size > 0
190
+ assert_instance_of BaseCmd::OutputLine, output_lines.sample
191
+ end
192
+
193
+ assert_equal exp.map{ |(h, ol)| h }, output_lines.map(&:host)
194
+ assert_equal exp.map{ |(h, ol)| ol.name }, output_lines.map(&:name)
195
+ assert_equal exp.map{ |(h, ol)| ol.line }, output_lines.map(&:line)
196
+ end
197
+
198
+ end
199
+
200
+ class CmdTests < UnitTests
201
+ desc "Cmd"
202
+ setup do
203
+ @cmd_class = @remote_class::Cmd
204
+ @cmd = @cmd_class.new(@cmd_str, :hosts => @hosts)
205
+ end
206
+ subject{ @cmd }
207
+
208
+ should "build a local cmd for each host with the cmd str, given opts" do
209
+ subject.hosts.each do |host|
210
+ assert_instance_of Dk::Local::Cmd, subject.local_cmds[host]
211
+ exp = ssh_cmd_str(@cmd_str, host, subject.ssh_args, subject.host_ssh_args)
212
+ assert_equal exp, subject.local_cmds[host].cmd_str
213
+ end
214
+ exp_cmd_str = ssh_cmd_str(
215
+ @cmd_str,
216
+ subject.hosts.last,
217
+ subject.ssh_args,
218
+ subject.host_ssh_args
219
+ )
220
+ exp_opts = {
221
+ :env => nil,
222
+ :dry_tree_run => nil
223
+ }
224
+ assert_equal [exp_cmd_str, exp_opts], @local_cmd_new_called_with
225
+
226
+ cmd = @cmd_class.new(@cmd_str, @opts)
227
+ cmd.hosts.each do |host|
228
+ assert_instance_of Dk::Local::Cmd, cmd.local_cmds[host]
229
+ exp = ssh_cmd_str(@cmd_str, host, cmd.ssh_args, cmd.host_ssh_args)
230
+ assert_equal exp, cmd.local_cmds[host].cmd_str
231
+ end
232
+ exp_cmd_str = ssh_cmd_str(
233
+ @cmd_str,
234
+ cmd.hosts.last,
235
+ cmd.ssh_args,
236
+ cmd.host_ssh_args
237
+ )
238
+ exp_opts = {
239
+ :env => @opts[:env],
240
+ :dry_tree_run => @opts[:dry_tree_run]
241
+ }
242
+ assert_equal [exp_cmd_str, exp_opts], @local_cmd_new_called_with
243
+ end
244
+
245
+ end
246
+
247
+ class CmdSpyTests < UnitTests
248
+ desc "CmdSpy"
249
+ setup do
250
+ @cmd_class = @remote_class::CmdSpy
251
+ @cmd = @cmd_class.new(@cmd_str, :hosts => @hosts)
252
+ end
253
+ subject{ @cmd }
254
+
255
+ should have_readers :cmd_opts
256
+ should have_imeths :run_input, :stdout=, :stderr=, :exitstatus=
257
+ should have_imeths :run_calls, :run_called?, :ssh?
258
+
259
+ should "build a local cmd spy for each host with the cmd str, given opts" do
260
+ subject.hosts.each do |host|
261
+ assert_instance_of Dk::Local::CmdSpy, subject.local_cmds[host]
262
+ exp = ssh_cmd_str(@cmd_str, host, subject.ssh_args, subject.host_ssh_args)
263
+ assert_equal exp, subject.local_cmds[host].cmd_str
264
+ end
265
+ exp_cmd_str = ssh_cmd_str(
266
+ @cmd_str,
267
+ subject.hosts.last,
268
+ subject.ssh_args,
269
+ subject.host_ssh_args
270
+ )
271
+ exp_opts = {
272
+ :env => nil,
273
+ :dry_tree_run => nil
274
+ }
275
+ assert_equal [exp_cmd_str, exp_opts], @local_cmd_spy_new_called_with
276
+
277
+ cmd = @cmd_class.new(@cmd_str, @opts)
278
+ cmd.hosts.each do |host|
279
+ assert_instance_of Dk::Local::CmdSpy, cmd.local_cmds[host]
280
+ exp = ssh_cmd_str(@cmd_str, host, cmd.ssh_args, cmd.host_ssh_args)
281
+ assert_equal exp, cmd.local_cmds[host].cmd_str
282
+ end
283
+ exp_cmd_str = ssh_cmd_str(
284
+ @cmd_str,
285
+ cmd.hosts.last,
286
+ cmd.ssh_args,
287
+ cmd.host_ssh_args
288
+ )
289
+ exp_opts = {
290
+ :env => @opts[:env],
291
+ :dry_tree_run => @opts[:dry_tree_run]
292
+ }
293
+ assert_equal [exp_cmd_str, exp_opts], @local_cmd_spy_new_called_with
294
+ end
295
+
296
+ should "know the input it was run with" do
297
+ input = Factory.string
298
+
299
+ assert_nil subject.run_input
300
+ subject.run(input)
301
+ assert_equal input, subject.run_input
302
+ end
303
+
304
+ should "demeter its first local cmd spy" do
305
+ first_local_cmd_spy = subject.local_cmds[subject.hosts.first]
306
+
307
+ stdout = Factory.stdout
308
+ subject.stdout = stdout
309
+ assert_equal stdout, first_local_cmd_spy.scmd.stdout
310
+
311
+ stderr = Factory.stderr
312
+ subject.stderr = stderr
313
+ assert_equal stderr, first_local_cmd_spy.scmd.stderr
314
+
315
+ exitstatus = Factory.exitstatus
316
+ subject.exitstatus = exitstatus
317
+ assert_equal exitstatus, first_local_cmd_spy.scmd.exitstatus
318
+
319
+ subject.run
320
+ assert_equal first_local_cmd_spy.scmd.start_calls, subject.run_calls
321
+ assert_equal first_local_cmd_spy.scmd.start_called?, subject.run_called?
322
+ end
323
+
324
+ should "be ssh" do
325
+ assert_true subject.ssh?
326
+ end
327
+
328
+ end
329
+
330
+ end