jenkins_api_client 0.6.2 → 0.7.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 (40) hide show
  1. data/.gitignore +3 -0
  2. data/.jenkins.yml +9 -0
  3. data/.travis.yml +11 -15
  4. data/CHANGELOG.md +15 -0
  5. data/Gemfile +2 -2
  6. data/README.md +7 -9
  7. data/Rakefile +27 -14
  8. data/lib/jenkins_api_client.rb +36 -6
  9. data/lib/jenkins_api_client/build_queue.rb +213 -0
  10. data/lib/jenkins_api_client/cli/base.rb +10 -6
  11. data/lib/jenkins_api_client/cli/helper.rb +13 -4
  12. data/lib/jenkins_api_client/cli/job.rb +6 -9
  13. data/lib/jenkins_api_client/cli/node.rb +6 -4
  14. data/lib/jenkins_api_client/cli/system.rb +2 -1
  15. data/lib/jenkins_api_client/client.rb +31 -25
  16. data/lib/jenkins_api_client/job.rb +248 -95
  17. data/lib/jenkins_api_client/node.rb +128 -10
  18. data/lib/jenkins_api_client/system.rb +4 -2
  19. data/lib/jenkins_api_client/version.rb +2 -2
  20. data/lib/jenkins_api_client/view.rb +17 -4
  21. data/scripts/login_with_irb.rb +4 -3
  22. data/spec/func_tests/client_spec.rb +90 -0
  23. data/spec/func_tests/job_spec.rb +348 -0
  24. data/spec/func_tests/node_spec.rb +174 -0
  25. data/spec/{spec_helper.rb → func_tests/spec_helper.rb} +2 -2
  26. data/spec/func_tests/system_spec.rb +55 -0
  27. data/spec/func_tests/view_spec.rb +53 -0
  28. data/spec/unit_tests/client_spec.rb +211 -0
  29. data/spec/unit_tests/fixtures/files/computer_sample.xml +17 -0
  30. data/spec/unit_tests/fixtures/files/job_sample.xml +16 -0
  31. data/spec/unit_tests/job_spec.rb +355 -0
  32. data/spec/unit_tests/node_spec.rb +192 -0
  33. data/spec/unit_tests/spec_helper.rb +8 -0
  34. data/spec/unit_tests/system_spec.rb +54 -0
  35. data/spec/unit_tests/view_spec.rb +127 -0
  36. metadata +34 -23
  37. data/spec/client_spec.rb +0 -52
  38. data/spec/job_spec.rb +0 -158
  39. data/spec/node_spec.rb +0 -48
  40. data/spec/system_spec.rb +0 -46
@@ -0,0 +1,17 @@
1
+ <slave>
2
+ <name>slave</name>
3
+ <description/>
4
+ <remoteFS>/var/jenkins</remoteFS>
5
+ <numExecutors>20</numExecutors>
6
+ <mode>NORMAL</mode>
7
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
8
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves@0.21">
9
+ <host>127.0.0.1</host>
10
+ <port>22</port>
11
+ <password>supersecret</password>
12
+ <privatekey>/root/.ssh/api_user_key</privatekey>
13
+ </launcher>
14
+ <label>slave</label>
15
+ <nodeProperties/>
16
+ <userId>kannan</userId>
17
+ </slave>
@@ -0,0 +1,16 @@
1
+ <project>
2
+ <actions/>
3
+ <description/>
4
+ <keepDependencies>false</keepDependencies>
5
+ <properties/>
6
+ <scm class="hudson.scm.NullSCM"/>
7
+ <canRoam>true</canRoam>
8
+ <disabled>false</disabled>
9
+ <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
10
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
11
+ <triggers class="vector"/>
12
+ <concurrentBuild>false</concurrentBuild>
13
+ <builders/>
14
+ <publishers/>
15
+ <buildWrappers/>
16
+ </project>
@@ -0,0 +1,355 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require 'net/http'
3
+
4
+ describe JenkinsApi::Client::Job do
5
+ context "With properly initialized Client and all methods defined" do
6
+
7
+ before do
8
+ @client = mock
9
+ @job = JenkinsApi::Client::Job.new(@client)
10
+ @sample_json_response = {
11
+ "jobs" => [
12
+ {"name" => "test_job"},
13
+ {"name" => "test_job2"}
14
+ ]
15
+ }
16
+ @sample_json_job_response = {
17
+ "downstreamProjects" => ["test_job1"],
18
+ "upstreamProjects" => ["test_job2"],
19
+ "builds" => [],
20
+ "color" => "running",
21
+ "nextBuildNumber" => 2
22
+ }
23
+ @sample_job_xml = File.read(
24
+ File.expand_path('../fixtures/files/job_sample.xml', __FILE__))
25
+ end
26
+
27
+ describe "InstanceMethods" do
28
+
29
+ describe "#create_job" do
30
+ it "accepts job_name and xml and creates the job" do
31
+ job_name = 'test_job'
32
+ xml = '<name>somename</name>'
33
+ @client.should_receive(:post_config)
34
+ @job.create(job_name, xml)
35
+ end
36
+ end
37
+
38
+ describe "#create_freestyle" do
39
+ it "creates a simple freestyle job" do
40
+ params = {
41
+ :name => 'test_job_using_params'
42
+ }
43
+ @client.should_receive(:post_config)
44
+ @job.create_freestyle(params)
45
+ end
46
+ it "creates a freestyle job with shell command" do
47
+ params = {
48
+ :name => "test_job_using_params_shell",
49
+ :shell_command => "echo this is a freestyle project"
50
+ }
51
+ @client.should_receive(:post_config)
52
+ @job.create_freestyle(params)
53
+ end
54
+ it "accepts Git SCM provider" do
55
+ params = {
56
+ :name => "test_job_using_params_git",
57
+ :scm_provider => "git",
58
+ :scm_url => "git://github.com/arangamani/jenkins_api_client/git",
59
+ :scm_branch => "master"
60
+ }
61
+ @client.should_receive(:post_config)
62
+ @job.create_freestyle(params)
63
+ end
64
+ it "accepts subversion SCM provider" do
65
+ params = {
66
+ :name => "test_job_using_params_subversion",
67
+ :scm_provider => "subversion",
68
+ :scm_url => "http://svn.freebsd.org/base",
69
+ :scm_branch => "master"
70
+ }
71
+ @client.should_receive(:post_config)
72
+ @job.create_freestyle(params)
73
+ end
74
+ it "accepts CVS SCM provider with branch" do
75
+ params = {
76
+ :name => "test_job_using_params_cvs_branch",
77
+ :scm_provider => "cvs",
78
+ :scm_url => "http://cvs.NetBSD.org",
79
+ :scm_module => "src",
80
+ :scm_branch => "MAIN"
81
+ }
82
+ @client.should_receive(:post_config)
83
+ @job.create_freestyle(params)
84
+ end
85
+ it "accepts CVS SCM provider with tag" do
86
+ params = {
87
+ :name => "test_job_using_params_cvs_tag",
88
+ :scm_provider => "cvs",
89
+ :scm_url => "http://cvs.NetBSD.org",
90
+ :scm_module => "src",
91
+ :scm_tag => "MAIN"
92
+ }
93
+ @client.should_receive(:post_config)
94
+ @job.create_freestyle(params)
95
+ end
96
+ end
97
+
98
+ describe "#delete" do
99
+ it "accepts the job name and deletes the job" do
100
+ @client.should_receive(:api_post_request)
101
+ @job.delete('test_job')
102
+ end
103
+ end
104
+
105
+ describe "#stop_build" do
106
+ it "accepts the job name and build number and stops the build" do
107
+ @client.should_receive(:api_get_request).twice.and_return(
108
+ "building" => true, "nextBuildNumber" => 2)
109
+ @client.should_receive(:api_post_request)
110
+ @job.stop_build('test_job')
111
+ end
112
+ end
113
+
114
+ describe "#get_console_output" do
115
+ it "accepts the job name and the obtains the console output" do
116
+ @client.should_receive(:api_get_request).and_return(
117
+ Net::HTTP.get_response(URI('http://example.com/index.html')))
118
+ @job.get_console_output('test_job', 1, 0, 'text')
119
+ end
120
+
121
+ it "raises an error if invalid mode is specified" do
122
+ expect(
123
+ lambda do
124
+ @job.get_console_output('test_job', 1, 0, 'image')
125
+ end
126
+ ).to raise_error
127
+ end
128
+ end
129
+
130
+ describe "#list_all" do
131
+ it "accepts no parameters and returns all jobs in an array" do
132
+ @client.should_receive(:api_get_request).and_return(
133
+ @sample_json_response)
134
+ response = @job.list_all
135
+ response.class.should == Array
136
+ response.size.should == @sample_json_response["jobs"].size
137
+ end
138
+ end
139
+
140
+ describe "#exists?" do
141
+ it "accepts a job name and returns true if the job exists" do
142
+ @client.should_receive(:api_get_request).and_return(
143
+ @sample_json_response)
144
+ @job.exists?("test_job").should == true
145
+ end
146
+ end
147
+
148
+ describe "#list_by_status" do
149
+ it "accepts the status and returns jobs in specified status" do
150
+ @client.should_receive(:api_get_request).twice.and_return(
151
+ @sample_json_response)
152
+ @job.list_by_status("success").class.should == Array
153
+ end
154
+ it "accepts the status and returns the jobs in specified status" do
155
+ @client.should_receive(:api_get_request).and_return(
156
+ @sample_json_response)
157
+ @job.list_by_status("success", ["test_job"]).class.should == Array
158
+ end
159
+ end
160
+
161
+ describe "#list" do
162
+ it "accepts a filter and returns all jobs matching the filter" do
163
+ @client.should_receive(:api_get_request).and_return(
164
+ "jobs" => ["test_job"])
165
+ @job.list("filter").class.should == Array
166
+ end
167
+ end
168
+
169
+ describe "#list_all_with_details" do
170
+ it "accepts no parameters and returns all jobs with details" do
171
+ @client.should_receive(:api_get_request).and_return(
172
+ @sample_json_response)
173
+ response = @job.list_all_with_details
174
+ response.class.should == Array
175
+ response.size.should == @sample_json_response["jobs"].size
176
+ end
177
+ end
178
+
179
+ describe "#list_details" do
180
+ it "accepts the job name and returns its details" do
181
+ @client.should_receive(:api_get_request).and_return(
182
+ @sample_json_response)
183
+ response = @job.list_details("test_job")
184
+ response.class.should == Hash
185
+ end
186
+ end
187
+
188
+ describe "#get_upstream_projects" do
189
+ it "accepts the job name and returns its upstream projects" do
190
+ @client.should_receive(:api_get_request).and_return(
191
+ @sample_json_job_response)
192
+ response = @job.get_upstream_projects("test_job")
193
+ response.class.should == Array
194
+ end
195
+ end
196
+
197
+ describe "#get_downstream_projects" do
198
+ it "accepts the job name and returns its downstream projects" do
199
+ @client.should_receive(:api_get_request).and_return(
200
+ @sample_json_job_response)
201
+ response = @job.get_downstream_projects("test_job")
202
+ response.class.should == Array
203
+ end
204
+ end
205
+
206
+ describe "#get_builds" do
207
+ it "accepts the job name and returns its builds" do
208
+ @client.should_receive(:api_get_request).and_return(
209
+ @sample_json_job_response)
210
+ response = @job.get_builds("test_job")
211
+ response.class.should == Array
212
+ end
213
+ end
214
+
215
+ describe "#color_to_status" do
216
+ it "accepts the color and convert it to correct status" do
217
+ @job.color_to_status("blue").should == "success"
218
+ @job.color_to_status("blue_anime").should == "running"
219
+ @job.color_to_status("red").should == "failure"
220
+ @job.color_to_status("red_anime").should == "running"
221
+ @job.color_to_status("yellow").should == "unstable"
222
+ @job.color_to_status("yellow_anime").should == "running"
223
+ @job.color_to_status("grey").should == "not_run"
224
+ @job.color_to_status("grey_anime").should == "running"
225
+ @job.color_to_status("aborted").should == "aborted"
226
+ end
227
+ it "returns invalid as the output if unknown color is detected" do
228
+ @job.color_to_status("orange").should == "invalid"
229
+ end
230
+ end
231
+
232
+ describe "#get_current_build_status" do
233
+ it "accepts the job name and returns its current build status" do
234
+ @client.should_receive(:api_get_request).and_return(
235
+ @sample_json_job_response)
236
+ @job.get_current_build_status("test_job").class.should == String
237
+ end
238
+ end
239
+
240
+ describe "#get_current_build_number" do
241
+ it "accepts the job name and returns its current build number" do
242
+ @client.should_receive(:api_get_request).and_return(
243
+ @sample_json_job_response)
244
+ @job.get_current_build_number("test_job").class.should == Fixnum
245
+ end
246
+ end
247
+
248
+ describe "#build" do
249
+ it "accepts the job name and builds the job" do
250
+ @client.should_receive(:api_post_request).with(
251
+ "/job/test_job/build").and_return(302)
252
+ @job.build("test_job").should == 302
253
+ end
254
+ end
255
+
256
+ describe "#get_config" do
257
+ it "accepts the job name and obtains its config.xml" do
258
+ @client.should_receive(:get_config).with(
259
+ "/job/test_job").and_return("<job>test_job</job>")
260
+ @job.get_config("test_job").should == "<job>test_job</job>"
261
+ end
262
+ end
263
+
264
+ describe "#post_config" do
265
+ it "accepts the job name and posts its config.xml to the server" do
266
+ @client.should_receive(:post_config).with(
267
+ "/job/test_job/config.xml", "<job>test_job</job>")
268
+ @job.post_config("test_job", "<job>test_job</job>")
269
+ end
270
+ end
271
+
272
+ describe "#change_description" do
273
+ it "accepts the job name and description and changes it" do
274
+ @client.should_receive(:get_config).with(
275
+ "/job/test_job").and_return(@sample_job_xml)
276
+ @client.should_receive(:post_config)
277
+ @job.change_description("test_job", "new description")
278
+ end
279
+ end
280
+
281
+ describe "#block_build_when_downstream_building" do
282
+ it "accepts the job name and blocks build when downstream builds" do
283
+ @client.should_receive(:get_config).with(
284
+ "/job/test_job").and_return(@sample_job_xml)
285
+ @client.should_receive(:post_config)
286
+ @job.block_build_when_downstream_building("test_job")
287
+ end
288
+ end
289
+
290
+ describe "#unblock_build_when_downstream_building" do
291
+ it "accepts the job name and unblocks build when downstream builds" do
292
+ @client.should_receive(:get_config).with(
293
+ "/job/test_job").and_return(@sample_job_xml)
294
+ @job.unblock_build_when_downstream_building("test_job")
295
+ end
296
+ end
297
+
298
+ describe "#block_build_when_upstream_building" do
299
+ it "accepts the job name and blocks build when upstream is building" do
300
+ @client.should_receive(:get_config).with(
301
+ "/job/test_job").and_return(@sample_job_xml)
302
+ @client.should_receive(:post_config)
303
+ @job.block_build_when_upstream_building("test_job")
304
+ end
305
+ end
306
+
307
+ describe "#unblock_build_when_upstream_building" do
308
+ it "accepts the job name and unblocks build when upstream builds" do
309
+ @client.should_receive(:get_config).with(
310
+ "/job/test_job").and_return(@sample_job_xml)
311
+ @job.unblock_build_when_upstream_building("test_job")
312
+ end
313
+ end
314
+
315
+ describe "#execute_concurrent_builds" do
316
+ it "accepts the job name and option and executes concurrent builds" do
317
+ @client.should_receive(:get_config).with(
318
+ "/job/test_job").and_return(@sample_job_xml)
319
+ @client.should_receive(:post_config)
320
+ @job.execute_concurrent_builds("test_job", true)
321
+ end
322
+ end
323
+
324
+ describe "#restrict_to_node" do
325
+ it "accepts the job name and node name and restricts the job node" do
326
+ @client.should_receive(:get_config).with(
327
+ "/job/test_job").and_return(@sample_job_xml)
328
+ @client.should_receive(:post_config)
329
+ @job.restrict_to_node("test_job", "test_slave")
330
+ end
331
+ end
332
+
333
+ describe "#unchain" do
334
+ it "accepts the job names and unchains them" do
335
+ @client.should_receive(:debug).and_return(false)
336
+ @client.should_receive(:get_config).with(
337
+ "/job/test_job").and_return(@sample_job_xml)
338
+ @client.should_receive(:post_config)
339
+ @job.unchain(["test_job"])
340
+ end
341
+ end
342
+
343
+ describe "#chain" do
344
+ it "accepts the job names and other options and chains them" do
345
+ @client.should_receive(:debug).and_return(false)
346
+ @client.should_receive(:get_config).with(
347
+ "/job/test_job").and_return(@sample_job_xml)
348
+ @client.should_receive(:post_config)
349
+ @job.unchain(["test_job"])
350
+ end
351
+ end
352
+
353
+ end
354
+ end
355
+ end
@@ -0,0 +1,192 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe JenkinsApi::Client::Node do
4
+ context "With properly initialized Client" do
5
+ before do
6
+ @client = mock
7
+ @node = JenkinsApi::Client::Node.new(@client)
8
+ @sample_json_computer_response = {
9
+ "computer" => [
10
+ "displayName" => "slave"
11
+ ]
12
+ }
13
+ computer_sample_xml_filename = '../fixtures/files/computer_sample.xml'
14
+ @sample_computer_xml = File.read(
15
+ File.expand_path(computer_sample_xml_filename , __FILE__)
16
+ )
17
+ end
18
+
19
+ describe "InstanceMethods" do
20
+
21
+ describe "#initialize" do
22
+ it "initializes by receiving an instance of client object" do
23
+ expect(
24
+ lambda{ JenkinsApi::Client::Node.new(@client) }
25
+ ).not_to raise_error
26
+ end
27
+ end
28
+
29
+ describe "#create_dump_slave" do
30
+ it "creates a dump slave by accepting required params" do
31
+ @client.should_receive(
32
+ :api_get_request
33
+ ).with(
34
+ "/computer"
35
+ ).and_return(
36
+ @sample_json_computer_response
37
+ )
38
+ @client.should_receive(:api_post_request).and_return("302")
39
+ @node.create_dump_slave(
40
+ :name => "test_slave",
41
+ :slave_host => "10.10.10.10",
42
+ :private_key_file => "/root/.ssh/id_rsa"
43
+ )
44
+ end
45
+ it "fails if name is not given" do
46
+ expect(
47
+ lambda{
48
+ @node.create_dump_slave(
49
+ :slave_host => "10.10.10.10",
50
+ :private_key_file => "/root/.ssh/id_rsa"
51
+ )
52
+ }
53
+ ).to raise_error
54
+ end
55
+ it "fails if slave_host is not given" do
56
+ expect(
57
+ lambda{
58
+ @node.create_dump_slave(
59
+ :name => "test_slave",
60
+ :private_key_file => "/root/.ssh/id_rsa"
61
+ )
62
+ }
63
+ ).to raise_error
64
+ end
65
+ it "fails if private_key_file is not given" do
66
+ expect(
67
+ lambda{
68
+ @node.create_dump_slave(
69
+ :name => "test_slave",
70
+ :slave_host => "10.10.10.10"
71
+ )
72
+ }
73
+ ).to raise_error
74
+ end
75
+ end
76
+
77
+ describe "#delete" do
78
+ it "gets the node name and deletes if exists" do
79
+ slave_name = "slave"
80
+ @client.should_receive(
81
+ :api_get_request
82
+ ).with(
83
+ "/computer"
84
+ ).and_return(
85
+ @sample_json_computer_response
86
+ )
87
+ @client.should_receive(
88
+ :api_post_request
89
+ ).with(
90
+ "/computer/#{slave_name}/doDelete"
91
+ ).and_return(
92
+ "302"
93
+ )
94
+ @node.delete(slave_name).to_i.should == 302
95
+ end
96
+ it "fails if the given node doesn't exist in Jenkins" do
97
+ slave_name = "not_there"
98
+ @client.should_receive(
99
+ :api_get_request
100
+ ).with(
101
+ "/computer"
102
+ ).and_return(
103
+ @sample_json_computer_response
104
+ )
105
+ expect(
106
+ lambda{ @node.delete(slave_name) }
107
+ ).to raise_error
108
+ end
109
+ end
110
+
111
+ describe "#list" do
112
+ it "accepts filter and lists all nodes matching the filter" do
113
+ @client.should_receive(
114
+ :api_get_request
115
+ ).and_return(
116
+ @sample_json_computer_response
117
+ )
118
+ @node.list("slave").class.should == Array
119
+ end
120
+ end
121
+
122
+ describe "GeneralAttributes" do
123
+ general_attributes = JenkinsApi::Client::Node::GENERAL_ATTRIBUTES
124
+ general_attributes.each do |attribute|
125
+ describe "#get_#{attribute}" do
126
+ it "should get the #{attribute} attribute" do
127
+ @client.should_receive(
128
+ :api_get_request
129
+ ).and_return(
130
+ @sample_json_computer_response
131
+ )
132
+ @node.method("get_#{attribute}").call
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ describe "NodeProperties" do
139
+ node_properties = JenkinsApi::Client::Node::NODE_PROPERTIES
140
+ node_properties.each do |property|
141
+ describe "#is_#{property}?" do
142
+ it "should get the #{property} property" do
143
+ @client.should_receive(
144
+ :api_get_request
145
+ ).twice.and_return(
146
+ @sample_json_computer_response
147
+ )
148
+ @node.method("is_#{property}?").call("slave")
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ describe "NodeAttributes" do
155
+ node_attributes = JenkinsApi::Client::Node::NODE_ATTRIBUTES
156
+ node_attributes.each do |attribute|
157
+ describe "#get_node_#{attribute}" do
158
+ it "should get the #{attribute} node attribute" do
159
+ @client.should_receive(
160
+ :api_get_request
161
+ ).twice.and_return(
162
+ @sample_json_computer_response
163
+ )
164
+ @node.method("get_node_#{attribute}").call("slave")
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "#get_config" do
171
+ it "accepts the node name and obtains the config xml from the server" do
172
+ @client.should_receive(
173
+ :get_config
174
+ ).with(
175
+ "/computer/slave/config.xml"
176
+ ).and_return(
177
+ @sample_computer_xml
178
+ )
179
+ @node.get_config("slave")
180
+ end
181
+ end
182
+
183
+ describe "#post_config" do
184
+ it "accepts the node namd and config.xml and posts it to the server" do
185
+ @client.should_receive(:post_config)
186
+ @node.post_config("slave", @sample_computer_xml)
187
+ end
188
+ end
189
+
190
+ end
191
+ end
192
+ end