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,37 @@
1
+ require 'assert'
2
+ require 'dk/has_the_runs'
3
+
4
+ require 'much-plugin'
5
+
6
+ module Dk::HasTheRuns
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "Dk::HasTheRuns"
10
+ setup do
11
+ @mixin_class = Dk::HasTheRuns
12
+ @runs_class = Class.new{ include Dk::HasTheRuns }
13
+ end
14
+ subject{ @mixin_class }
15
+
16
+ should "use much-plugin" do
17
+ assert_includes MuchPlugin, subject
18
+ end
19
+
20
+ end
21
+
22
+ class InitTests < UnitTests
23
+ desc "when init"
24
+ setup do
25
+ @runs = @runs_class.new
26
+ end
27
+ subject{ @runs }
28
+
29
+ should have_imeths :runs
30
+
31
+ should "have no runs by default" do
32
+ assert_equal [], subject.runs
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,279 @@
1
+ require 'assert'
2
+ require 'dk/has_the_stubs'
3
+
4
+ require 'dk/local'
5
+ require 'dk/remote'
6
+
7
+ module Dk::HasTheStubs
8
+
9
+ class UnitTests < Assert::Context
10
+ desc "Dk::HasTheStubs"
11
+ setup do
12
+ @module = Dk::HasTheStubs
13
+ end
14
+ subject{ @module }
15
+
16
+ should "use much-plugin" do
17
+ assert_includes MuchPlugin, subject
18
+ end
19
+
20
+ end
21
+
22
+ class MixinTests < UnitTests
23
+ desc "mixed in"
24
+ setup do
25
+ @class = Class.new do
26
+ include Dk::HasTheStubs
27
+
28
+ def has_the_stubs_build_local_cmd(cmd_str, given_opts)
29
+ BuiltCmd.new(cmd_str, given_opts)
30
+ end
31
+
32
+ def has_the_stubs_build_remote_cmd(cmd_str, ssh_opts)
33
+ BuiltCmd.new(cmd_str, ssh_opts)
34
+ end
35
+ end
36
+ end
37
+ subject{ @class }
38
+
39
+ end
40
+
41
+ class InitTests < MixinTests
42
+ desc "when init"
43
+ setup do
44
+ raw_cmd_str = Factory.string
45
+ raw_input = Factory.string
46
+ raw_given_opts = { Factory.string => Factory.string }
47
+
48
+ @cmd_str = [raw_cmd_str, proc{ "#{raw_cmd_str},#{some_attr}" }].sample
49
+ @input = [raw_input, proc{ "#{raw_input},#{some_attr}" }].sample
50
+ @given_opts = [
51
+ raw_given_opts,
52
+ proc{ raw_given_opts.merge('some_attr' => some_attr) }
53
+ ].sample
54
+ @ssh_opts = { :hosts => Factory.hosts }
55
+ @stub_block = Proc.new{ |s| Factory.string }
56
+
57
+ task_class = Class.new{ def some_attr; @some_attr ||= Factory.string; end }
58
+ @task = task_class.new
59
+ @instance = @class.new
60
+ end
61
+ subject{ @instance }
62
+
63
+ should have_imeths :local_cmd_stubs, :stub_cmd, :unstub_all_cmds
64
+ should have_imeths :remote_cmd_stubs, :stub_ssh, :unstub_all_ssh
65
+
66
+ should "allow stubbing cmds" do
67
+ assert_equal 0, subject.local_cmd_stubs.size
68
+
69
+ cmd_str = get_raw_value(@cmd_str)
70
+ input = get_raw_value(@input)
71
+ given_opts = get_raw_value(@given_opts)
72
+
73
+ subject.stub_cmd(@cmd_str, &@stub_block)
74
+ assert_equal 1, subject.local_cmd_stubs.size
75
+ assert_equal @stub_block, lookup_cmd_stub_block(cmd_str, nil, nil)
76
+
77
+ subject.stub_cmd(@cmd_str, :input => @input, &@stub_block)
78
+ assert_equal 2, subject.local_cmd_stubs.size
79
+ assert_equal @stub_block, lookup_cmd_stub_block(cmd_str, input, nil)
80
+
81
+ subject.stub_cmd(@cmd_str, :opts => @given_opts, &@stub_block)
82
+ assert_equal 3, subject.local_cmd_stubs.size
83
+ assert_equal @stub_block, lookup_cmd_stub_block(cmd_str, nil, given_opts)
84
+
85
+ subject.stub_cmd(@cmd_str, {
86
+ :input => @input,
87
+ :opts => @given_opts
88
+ }, &@stub_block)
89
+ assert_equal 4, subject.local_cmd_stubs.size
90
+ assert_equal @stub_block, lookup_cmd_stub_block(cmd_str, input, given_opts)
91
+ end
92
+
93
+ should "allow unstubbing all cmds" do
94
+ subject.stub_cmd(@cmd_str, &@stub_block)
95
+ subject.stub_cmd(@cmd_str, :input => @input, &@stub_block)
96
+ subject.stub_cmd(@cmd_str, :opts => @given_opts, &@stub_block)
97
+ subject.stub_cmd(@cmd_str, {
98
+ :input => @input,
99
+ :opts => @given_opts
100
+ }, &@stub_block)
101
+
102
+ assert_equal 4, subject.local_cmd_stubs.size
103
+ subject.unstub_all_cmds
104
+ assert_equal 0, subject.local_cmd_stubs.size
105
+ end
106
+
107
+ should "allow stubbing ssh" do
108
+ assert_equal 0, subject.remote_cmd_stubs.size
109
+
110
+ cmd_str = get_raw_value(@cmd_str)
111
+ input = get_raw_value(@input)
112
+ given_opts = get_raw_value(@given_opts)
113
+
114
+ subject.stub_ssh(@cmd_str, &@stub_block)
115
+ assert_equal 1, subject.remote_cmd_stubs.size
116
+ assert_equal @stub_block, lookup_ssh_stub_block(cmd_str, nil, nil)
117
+
118
+ subject.stub_ssh(@cmd_str, :input => @input, &@stub_block)
119
+ assert_equal 2, subject.remote_cmd_stubs.size
120
+ assert_equal @stub_block, lookup_ssh_stub_block(cmd_str, input, nil)
121
+
122
+ subject.stub_ssh(@cmd_str, :opts => @given_opts, &@stub_block)
123
+ assert_equal 3, subject.remote_cmd_stubs.size
124
+ assert_equal @stub_block, lookup_ssh_stub_block(cmd_str, nil, given_opts)
125
+
126
+ subject.stub_ssh(@cmd_str, {
127
+ :input => @input,
128
+ :opts => @given_opts
129
+ }, &@stub_block)
130
+ assert_equal 4, subject.remote_cmd_stubs.size
131
+ assert_equal @stub_block, lookup_ssh_stub_block(cmd_str, input, given_opts)
132
+ end
133
+
134
+ should "allow unstubbing all ssh" do
135
+ subject.stub_ssh(@cmd_str, &@stub_block)
136
+ subject.stub_ssh(@cmd_str, :input => @input, &@stub_block)
137
+ subject.stub_ssh(@cmd_str, :opts => @given_opts, &@stub_block)
138
+ subject.stub_ssh(@cmd_str, {
139
+ :input => @input,
140
+ :opts => @given_opts
141
+ }, &@stub_block)
142
+
143
+ assert_equal 4, subject.remote_cmd_stubs.size
144
+ subject.unstub_all_ssh
145
+ assert_equal 0, subject.remote_cmd_stubs.size
146
+ end
147
+
148
+ # test the `Runner` interface that this overwrites, these are private
149
+ # methods but since they overwrite the runner's interface we want to test
150
+ # them as if they were public methods
151
+
152
+ should "use stubs with `build_local_cmd`" do
153
+ task = @task
154
+ cmd_str = get_raw_value(@cmd_str)
155
+ input = get_raw_value(@input)
156
+ given_opts = get_raw_value(@given_opts)
157
+
158
+ subject.stub_cmd(@cmd_str){ |s| s.exitstatus = 1 }
159
+ spy = subject.instance_eval do
160
+ build_local_cmd(task, cmd_str, nil, nil)
161
+ end
162
+ assert_false spy.success?
163
+
164
+ subject.unstub_all_cmds
165
+ subject.stub_cmd(@cmd_str, :input => @input){ |s| s.exitstatus = 1 }
166
+ spy = subject.instance_eval do
167
+ build_local_cmd(task, cmd_str, input, nil)
168
+ end
169
+ assert_false spy.success?
170
+
171
+ subject.unstub_all_cmds
172
+ subject.stub_cmd(@cmd_str, :opts => @given_opts){ |s| s.exitstatus = 1 }
173
+ spy = subject.instance_eval do
174
+ build_local_cmd(task, cmd_str, nil, given_opts)
175
+ end
176
+ assert_false spy.success?
177
+
178
+ subject.unstub_all_cmds
179
+ subject.stub_cmd(@cmd_str, {
180
+ :input => @input,
181
+ :opts => @given_opts
182
+ }){ |s| s.exitstatus = 1 }
183
+ spy = subject.instance_eval do
184
+ build_local_cmd(task, cmd_str, input, given_opts)
185
+ end
186
+ assert_false spy.success?
187
+ end
188
+
189
+ should "defer to `has_the_stubs_build_local_cmd` when cmd isn't stubbed" do
190
+ task = @task
191
+ cmd_str = get_raw_value(@cmd_str)
192
+ input = get_raw_value(@input)
193
+ given_opts = get_raw_value(@given_opts)
194
+
195
+ result = subject.instance_eval do
196
+ build_local_cmd(task, cmd_str, input, given_opts)
197
+ end
198
+ assert_equal BuiltCmd.new(cmd_str, given_opts), result
199
+ end
200
+
201
+ should "use stubs with `build_remote_cmd`" do
202
+ task = @task
203
+ cmd_str = get_raw_value(@cmd_str)
204
+ input = get_raw_value(@input)
205
+ given_opts = get_raw_value(@given_opts)
206
+ ssh_opts = @ssh_opts
207
+
208
+ subject.stub_ssh(@cmd_str){ |s| s.exitstatus = 1 }
209
+ spy = subject.instance_eval do
210
+ build_remote_cmd(task, cmd_str, nil, nil, ssh_opts)
211
+ end
212
+ assert_false spy.success?
213
+
214
+ subject.unstub_all_ssh
215
+ subject.stub_ssh(@cmd_str, :input => @input){ |s| s.exitstatus = 1 }
216
+ spy = subject.instance_eval do
217
+ build_remote_cmd(task, cmd_str, input, nil, ssh_opts)
218
+ end
219
+ assert_false spy.success?
220
+
221
+ subject.unstub_all_ssh
222
+ subject.stub_ssh(@cmd_str, :opts => @given_opts){ |s| s.exitstatus = 1 }
223
+ spy = subject.instance_eval do
224
+ build_remote_cmd(task, cmd_str, nil, given_opts, ssh_opts)
225
+ end
226
+ assert_false spy.success?
227
+
228
+ subject.unstub_all_ssh
229
+ subject.stub_ssh(@cmd_str, {
230
+ :input => @input,
231
+ :opts => @given_opts
232
+ }){ |s| s.exitstatus = 1 }
233
+ spy = subject.instance_eval do
234
+ build_remote_cmd(task, cmd_str, input, given_opts, ssh_opts)
235
+ end
236
+ assert_false spy.success?
237
+ end
238
+
239
+ should "defer to `has_the_stubs_build_remote_cmd` when cmd isn't stubbed" do
240
+ task = @task
241
+ cmd_str = get_raw_value(@cmd_str)
242
+ input = get_raw_value(@input)
243
+ given_opts = get_raw_value(@given_opts)
244
+ ssh_opts = @ssh_opts
245
+
246
+ result = subject.instance_eval do
247
+ build_remote_cmd(task, cmd_str, input, given_opts, ssh_opts)
248
+ end
249
+ assert_equal BuiltCmd.new(cmd_str, ssh_opts), result
250
+ end
251
+
252
+ private
253
+
254
+ def get_raw_value(value)
255
+ value.kind_of?(::Proc) ? @task.instance_eval(&value) : value
256
+ end
257
+
258
+ def lookup_cmd_stub_block(cmd_str, input, given_opts)
259
+ instance = subject
260
+ task = @task
261
+ subject.instance_eval do
262
+ find_cmd_ssh_stub_block(instance.local_cmd_stubs, task, cmd_str, input, given_opts)
263
+ end
264
+ end
265
+
266
+ def lookup_ssh_stub_block(cmd_str, input, given_opts)
267
+ instance = subject
268
+ task = @task
269
+ subject.instance_eval do
270
+ find_cmd_ssh_stub_block(instance.remote_cmd_stubs, task, cmd_str, input, given_opts)
271
+ end
272
+ end
273
+
274
+ end
275
+
276
+ BuiltCmd = Struct.new(:cmd_str, :opts)
277
+
278
+ end
279
+
@@ -0,0 +1,174 @@
1
+ require 'assert'
2
+ require 'dk/local'
3
+
4
+ require 'scmd/command_spy'
5
+
6
+ module Dk::Local
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "Dk::Local"
10
+ setup do
11
+ @cmd_str = Factory.string
12
+ @scmd_spy = Scmd::CommandSpy.new(@cmd_str).tap do |spy|
13
+ spy.exitstatus = Factory.exitstatus
14
+ spy.stdout = [Factory.stdout, nil].sample
15
+ spy.stderr = [Factory.stderr, nil].sample
16
+ end
17
+
18
+ @scmd_new_called_with = nil
19
+ Assert.stub(Scmd, :new) do |*args|
20
+ @scmd_new_called_with = args
21
+ @scmd_spy
22
+ end
23
+
24
+ @scmd_cmd_new_called_with = nil
25
+ Assert.stub(Scmd::Command, :new) do |*args|
26
+ @scmd_cmd_new_called_with = args
27
+ @scmd_spy
28
+ end
29
+
30
+ @scmd_spy_new_called_with = nil
31
+ Assert.stub(Scmd::CommandSpy, :new) do |*args|
32
+ @scmd_spy_new_called_with = args
33
+ @scmd_spy
34
+ end
35
+ end
36
+ subject{ @cmd }
37
+
38
+ end
39
+
40
+ class BaseCmdTests < UnitTests
41
+ desc "BaseCmd"
42
+ setup do
43
+ @cmd_class = Dk::Local::BaseCmd
44
+ @opts = {
45
+ :env => Factory.string,
46
+ Factory.string => Factory.string
47
+ }
48
+
49
+ @cmd = @cmd_class.new(Scmd, @cmd_str, @opts)
50
+ end
51
+
52
+ should have_readers :scmd, :cmd_str
53
+ should have_imeths :to_s, :run
54
+ should have_imeths :stdout, :stderr, :success?, :output_lines
55
+
56
+ should "build an scmd with the cmd str and any given :env option" do
57
+ assert_equal @scmd_spy, subject.scmd
58
+ assert_equal [@cmd_str, { :env => @opts[:env] }], @scmd_new_called_with
59
+
60
+ cmd = @cmd_class.new(Scmd::CommandSpy, @cmd_str, @opts)
61
+ assert_equal @scmd_spy, cmd.scmd
62
+ assert_equal [@cmd_str, { :env => @opts[:env] }], @scmd_spy_new_called_with
63
+ end
64
+
65
+ should "know its cmd str" do
66
+ assert_equal @cmd_str, subject.cmd_str
67
+ assert_equal subject.cmd_str, subject.to_s
68
+ end
69
+
70
+ should "demeter its scmd" do
71
+ assert_false @scmd_spy.run_called?
72
+ input = Factory.string
73
+ subject.run(input)
74
+ assert_true @scmd_spy.run_called?
75
+ assert_equal input, @scmd_spy.run_calls.last.input
76
+
77
+ assert_equal @scmd_spy.stdout, subject.stdout
78
+ assert_equal @scmd_spy.stderr, subject.stderr
79
+ assert_equal @scmd_spy.success?, subject.success?
80
+ end
81
+
82
+ should "know its output lines" do
83
+ stdout_lines = subject.stdout.to_s.split("\n")
84
+ stderr_lines = subject.stderr.to_s.split("\n")
85
+ output_lines = subject.output_lines
86
+
87
+ exp = (stdout_lines + stderr_lines).size
88
+ assert_equal exp, output_lines.size
89
+
90
+ if output_lines.size > 0
91
+ assert_instance_of BaseCmd::OutputLine, output_lines.sample
92
+ end
93
+
94
+ exp = stdout_lines.size.times.map{ 'stdout' } +
95
+ stderr_lines.size.times.map{ 'stderr' }
96
+ assert_equal exp, output_lines.map(&:name)
97
+
98
+ exp = stdout_lines + stderr_lines
99
+ assert_equal exp, output_lines.map(&:line)
100
+ end
101
+
102
+ end
103
+
104
+ class CmdTests < UnitTests
105
+ desc "Cmd"
106
+ setup do
107
+ @cmd_class = Dk::Local::Cmd
108
+ @cmd = @cmd_class.new(@cmd_str)
109
+ end
110
+
111
+ should "build an Scmd with the cmd str and any given options" do
112
+ assert_equal [@cmd_str, { :env => nil }], @scmd_new_called_with
113
+
114
+ opts = { :env => Factory.string }
115
+ cmd = @cmd_class.new(@cmd_str, opts)
116
+ assert_equal [@cmd_str, { :env => opts[:env] }], @scmd_new_called_with
117
+ end
118
+
119
+ end
120
+
121
+ class CmdSpyTests < UnitTests
122
+ desc "CmdSpy"
123
+ setup do
124
+ @cmd_class = Dk::Local::CmdSpy
125
+ @cmd = @cmd_class.new(@cmd_str)
126
+ end
127
+
128
+ should have_readers :cmd_opts
129
+ should have_imeths :run_input, :stdout=, :stderr=, :exitstatus=
130
+ should have_imeths :run_calls, :run_called?, :ssh?
131
+
132
+ should "build an scmd spy with the cmd str and any given options" do
133
+ assert_equal [@cmd_str, { :env => nil }], @scmd_spy_new_called_with
134
+ assert_nil subject.cmd_opts
135
+
136
+ opts = { :env => Factory.string }
137
+ cmd = @cmd_class.new(@cmd_str, opts)
138
+ assert_equal [@cmd_str, { :env => opts[:env] }], @scmd_spy_new_called_with
139
+ assert_equal opts, cmd.cmd_opts
140
+ end
141
+
142
+ should "know the input it was run with" do
143
+ input = Factory.string
144
+
145
+ assert_nil subject.run_input
146
+ subject.run(input)
147
+ assert_equal input, subject.run_input
148
+ end
149
+
150
+ should "demeter its scmd spy" do
151
+ stdout = Factory.stdout
152
+ subject.stdout = stdout
153
+ assert_equal stdout, @scmd_spy.stdout
154
+
155
+ stderr = Factory.stderr
156
+ subject.stderr = stderr
157
+ assert_equal stderr, @scmd_spy.stderr
158
+
159
+ exitstatus = Factory.exitstatus
160
+ subject.exitstatus = exitstatus
161
+ assert_equal exitstatus, @scmd_spy.exitstatus
162
+
163
+ subject.run
164
+ assert_equal @scmd_spy.run_calls, subject.run_calls
165
+ assert_equal @scmd_spy.run_called?, subject.run_called?
166
+ end
167
+
168
+ should "not be ssh" do
169
+ assert_false subject.ssh?
170
+ end
171
+
172
+ end
173
+
174
+ end
@@ -0,0 +1,17 @@
1
+ require 'assert'
2
+ require 'dk/null_logger'
3
+
4
+ class Dk::NullLogger
5
+
6
+ class UnitTests < Assert::Context
7
+ desc "Dk::NullLogger"
8
+ setup do
9
+ @null_logger = Dk::NullLogger.new
10
+ end
11
+ subject{ @null_logger }
12
+
13
+ should have_imeths :info, :debug, :error
14
+
15
+ end
16
+
17
+ end